强制转换

在 C++ 中,如果类派生自包含一个或多个虚拟函数的基类,则指向该基类类型的指针可用于调用派生类对象中的虚拟函数。 包含虚函数的类有时被称为“多态类”。

类层次结构图,其中 C 派生自 B,B 派生自 A。
类层次结构

C类型的对象可以如下所示进行可视化:

具有子对象 B 和 A 的类 C 的关系图。
具有子对象 B 和 A 的类 C

给定C类的一个实例,存在B子对象和A子对象。 包括 CA 子对象的 B 实例是“完整对象。”

由于派生类完全包含它派生自的所有基类的定义,因此将指针转换至其基类中的任何一个都是安全的(也称为向上转换)。 鉴于指向基类的指针,可以安全地将指针强制转换为派生类的实例(也称为向下转换)。

通过使用运行时类型信息,可以检查指针实际是否指向完整对象,并可以安全转换以指向其层次结构中的另一个对象。 dynamic_cast运算符执行运行时检查以确保操作安全。 最好设计类层次结构,以便可以使用虚拟函数来避免向下转换的需要。 但是,如果必须向下转换,请使用dynamic_cast确保操作安全。

对于非多态类型的转换,可以使用static_cast运算符(本主题说明静态和动态强制转换之间的差异,以及何时适合使用它们)。

以下示例演示了 dynamic_caststatic_cast 的用法:

#include <iostream>

class Base {
public:
    virtual void print() { std::cout << "Base\n"; }
};

class Derived1 : public Base {
public:
    void print() override { std::cout << "Derived1\n"; }
};

class Derived2 : public Base {
public:
    void print() override { std::cout << "Derived2\n"; }
};

class MostDerived : public Derived1, public Derived2 {
public:
    void print() override { std::cout << "MostDerived\n"; }
};

int main() {
    MostDerived md;
    Base* b1 = static_cast<Derived1*>(&md); // Upcast to Derived1 is safe
    Base* b2 = static_cast<Derived2*>(&md); // Upcast to Derived2 is safe

    // Downcast to MostDerived is ambiguous and unsafe
    // MostDerived* md1 = static_cast<MostDerived*>(b1); // This won't compile
    // MostDerived* md2 = static_cast<MostDerived*>(b2); // This won't compile

    // Correct way to downcast in this situation
    MostDerived* md1 = dynamic_cast<MostDerived*>(b1); // This is safe
    MostDerived* md2 = dynamic_cast<MostDerived*>(b2); // This is safe

    md1->print(); // Prints "MostDerived"
    md2->print(); // Prints "MostDerived"

    return 0;
}

本部分涵盖了以下主题:

另请参阅

表达式