存在向上类型转换,在类层次向上移动,那也应该存在可以向下移动的向下
类型转换。但是由于在一个继承层次上向上移动时,类总是集中于更一般的类,
因此向上类型转换是容易的
C++提供了一个特殊的称为dynamic_cast的显式类型转换,它就是一种安全
类型向下类型转换的操作
//: C15:DynamicCast.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#include <iostream>
using namespace std;
class Pet { public: virtual ~Pet(){}};
class Dog : public Pet {};
class Cat : public Pet {};
int main() {
Pet* b = new Cat; // Upcast
// Try to cast it to Dog*:
Dog* d1 = dynamic_cast<Dog*>(b);
// Try to cast it to Cat*:
Cat* d2 = dynamic_cast<Cat*>(b);
cout << "d1 = " << (long)d1 << endl;
cout << "d2 = " << (long)d2 << endl;
getchar();
} ///:~
当使用dynamic_cast时,必须对一个真正多态的层次进行操作--它含有虚
函数--这因为dynamic_cast使用了存储在VTABLE中的信息来判断实际的类型
输出
d1 = 0
d2 = 8538144
dynamic_cast运行时需要一点额外的开销,不多,但如果执行大量的dynamic_cast,
就会影响性能
有时,在进行向下类型转换时,我们可以知道正在处理的是何种类型,这时使用dynamic_cast
产生额外的开销就没有必要,可以通过使用static_cast来代替它
//: C15:StaticHierarchyNavigation.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Navigating class hierarchies with static_cast
#include <iostream>
#include <typeinfo>
using namespace std;
class Shape { public: virtual ~Shape() {}; };
class Circle : public Shape {};
class Square : public Shape {};
class Other {};
int main() {
Circle c;
Shape* s = &c; // Upcast: normal and OK
// More explicit but unnecessary:
s = static_cast<Shape*>(&c);
// (Since upcasting is such a safe and common
// operation, the cast becomes cluttering)
Circle* cp = 0;
Square* sp = 0;
// Static Navigation of class hierarchies
// requires extra type information:
if(typeid(s) == typeid(cp)) // C++ RTTI
cp = static_cast<Circle*>(s);
if(typeid(s) == typeid(sp))
sp = static_cast<Square*>(s);
if(cp != 0)
cout << "It's a circle!" << endl;
if(sp != 0)
cout << "It's a square!" << endl;
// Static navigation is ONLY an efficiency hack;
// dynamic_cast is always safer. However:
// Other* op = static_cast<Other*>(s);
// Conveniently gives an error message, while
Other* op2 = (Other*)s;
// does not
getchar();
} ///:~
在这个程序中,使用一个新的特征,C++的运行时类型识别 RTTI机制
RTTI允许我们得到在进行向上类型转换时丢失的类型信息
程序创建一个Circle对象,它的地址被向上类型转换为Shape指针
RTTI用于判定类型,static_cast用于执行向下类型转换
如果类层次中没有虚函数,或者如果有其他的需要,要求我们安全地进行
向下类型转换