C++编程思想 第1卷 第15章 多态性和虚函数 向下类型转换

存在向上类型转换,在类层次向上移动,那也应该存在可以向下移动的向下
类型转换。但是由于在一个继承层次上向上移动时,类总是集中于更一般的类,
因此向上类型转换是容易的

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用于执行向下类型转换

如果类层次中没有虚函数,或者如果有其他的需要,要求我们安全地进行
向下类型转换

猜你喜欢

转载自blog.csdn.net/eyetired/article/details/81408033