thinking in c++卷2

类别:VC语言 点击:0 评论:0 推荐:

多重继承

RTTI必须与多重继承的所有复杂性正常工作,包括虚拟基类(在下一章深入讨论——你可以在阅读了第9章后回到这里)。

//: C08:RTTIandMultipleInheritance.cpp

#include <iostream>

#include <typeinfo>

using namespace std;

 

class BB {

public:

  virtual void f() {}

  virtual ~BB() {}

};

 

class B1 : virtual public BB {};

class B2 : virtual public BB {};

class MI : public B1, public B2 {};

 

int main() {

  BB* bbp = new MI; // Upcast

  // Proper name detection:

  cout << typeid(*bbp).name() << endl;

  // Dynamic_cast works properly:

  MI* mip = dynamic_cast<MI*>(bbp);

  // Can't force old-style cast:

//! MI* mip2 = (MI*)bbp; // Compile error

} ///:~

typeid( )操作符能正确的探测到实际对象的名字,甚至通过虚拟基类指针。dynamic_cast也能正确工作。但是编译器再不允许你用老方法来造型:

MI* mip = (MI*)bbp; // Compile-time error

编译器知道这永远也不会做正确的事,因此它需要你使用一个dynamic_cast。

 

正确使用RTTI(Sensible uses for RTTI)

因为你能够从一个匿名的多态指针发现类型信息和RTTI可以在虚拟函数作用之前就有意义,所以RTTI经常被新手误用。对很多有过程式编程背景的人们来说,叫他们不要用switch语句来将程序组织成集合是很困难的。他们可能用RTTI来完成这些,因而就丢失了代码开发和维护中多态的重要价值。C++的意图是让你在你的代码里使用虚函数,以及仅仅在你必须的时候使用RTTI。

无论如何,按照他们的意图使用需虚函数需要你有基类定义的控制权,因为在你扩展你的程序时,有时候你会发现基类并没有包含你需要的虚函数。如果基类来自一个库或者被其他人所控制,问题的一种解决办法就是RTTI,你可以衍生一个新的类型并加上你的额外成员函数。在代码的另外其他地方,你能探测到你的特殊类型和调用其成员函数。这并不会摧毁多态和程序的扩展性,因为加入一个新的类型并需要你搜寻switch语句。可是,当你向需要你的特性的main函数加入新代码时,你必须探测你的特殊类型。

本文地址:http://com.8s8s.com/it/it1028.htm