在 C++ 中,如果类派生自包含一个或多个虚拟函数的基类,则指向该基类类型的指针可用于调用派生类对象中的虚拟函数。 包含虚函数的类有时被称为“多态类”。
类层次结构
C
类型的对象可以如下所示进行可视化:
具有子对象 B 和 A 的类 C
给定C
类的一个实例,存在B
子对象和A
子对象。 包括 C
和 A
子对象的 B
实例是“完整对象。”
由于派生类完全包含它派生自的所有基类的定义,因此将指针转换至其基类中的任何一个都是安全的(也称为向上转换)。 鉴于指向基类的指针,可以安全地将指针强制转换为派生类的实例(也称为向下转换)。
通过使用运行时类型信息,可以检查指针实际是否指向完整对象,并可以安全转换以指向其层次结构中的另一个对象。 dynamic_cast运算符执行运行时检查以确保操作安全。 最好设计类层次结构,以便可以使用虚拟函数来避免向下转换的需要。 但是,如果必须向下转换,请使用dynamic_cast
确保操作安全。
对于非多态类型的转换,可以使用static_cast运算符(本主题说明静态和动态强制转换之间的差异,以及何时适合使用它们)。
以下示例演示了 dynamic_cast
和 static_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;
}
本部分涵盖了以下主题: