分享
 
 
 

thinkng in c++卷2

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

向中间层造型

正如你在前面使用Security类层次里所看到的,dynamic_cast能在一个有多个层的继承层次里探测到原来的类型和中间的类型。这儿是另一个例子:

//: C08:IntermediateCast.cpp

#include <cassert>

#include <typeinfo>

using namespace std;

class B1 {

public:

virtual ~B1() {}

};

class B2 {

public:

virtual ~B2() {}

};

class MI : public B1, public B2 {};

class Mi2 : public MI {};

int main() {

B2* b2 = new Mi2;

Mi2* mi2 = dynamic_cast<Mi2*>(b2);

MI* mi = dynamic_cast<MI*>(b2);

B1* b1 = dynamic_cast<B1*>(b2);

assert(typeid(b2) != typeid(Mi2*));

assert(typeid(b2) == typeid(B2*));

delete b2;

} ///:~

这个例子有多重继承的额外复杂性(你在本章的后面第9章学习更多关于多重继承的内容)。如果你创建了一个Mi2而且把他向上转换到根(在这种情况下,两个可能根中的一个被选到),dynamic_cast回到继承层MI或者Mi2是成功的。

你甚至能从一个根造型到另一个:

B1* b1 = dynamic_cast<B1*>(b2);

这是成功的因为B2事实上指向一个Mi2对象,它包含了一个类型为B1.的子对象。

向中间层造型在dynamic_cast和typeid之间产生了一个有趣的差异。Typeid操作符经常产生指向一个静态type_info对象的引用,该type_info对象描述了对象的动态型别。因此,他不会给你中间层的信息。在下面的表达式里(它为true), typeid不会将b2看作指向衍生类型的指针,象dynamic_cast一样:

typeid(b2) != typeid(Mi2*)

b2的类型就是该指针的实际类型:typeid(b2) == typeid(B2*)

void指针

RTTI仅仅对完整类型起作用,意味着使用typeid的时候所有的类信息都是可能用到。特别的,它不对void指针起作用:

//: C08:VoidRTTI.cpp

// RTTI & void pointers.

//!#include <iostream>

#include <typeinfo>

using namespace std;

class Stimpy {

public:

virtual void happy() {}

virtual void joy() {}

virtual ~Stimpy() {}

};

int main() {

void* v = new Stimpy;

// Error:

//! Stimpy* s = dynamic_cast<Stimpy*>(v);

// Error:

//! cout << typeid(*v).name() << endl;

} ///:~

Void实际上意味着“没有类型信息”。

RTTI用于模版

类模版与RTTI工作正常,因为它所有的事情就是产生类。像平常一样,RTTI提供了一个方便的获得你所在的类的名字的方法。下面的例子打印出构造函数和析构函数调用的顺序。

//: C08:ConstructorOrder.cpp

// Order of constructor calls.

#include <iostream>

#include <typeinfo>

using namespace std;

template<int id> class Announce {

public:

Announce() {

cout << typeid(*this).name() << " constructor" << endl;

}

~Announce() {

cout << typeid(*this).name() << " destructor" << endl;

}

};

class X : public Announce<0> {

Announce<1> m1;

Announce<2> m2;

public:

X() { cout << "X::X()" << endl; }

~X() { cout << "X::~X()" << endl; }

};

int main() { X x; } ///:~

这个模版用一个常整型来区别一个类和另一个类,但是类型参数也能工作。在构造函数和析构函数内部,RTTI信息产生了打印的类名字。类X用继承和组合来产生一个类,该类的构造和析构函数调用顺序很有趣。输出是:

Announce<0> constructor

Announce<1> constructor

Announce<2> constructor

X::X()

X::~X()

Announce<2> destructor

Announce<1> destructor

Announce<0> destructor

当然,你也能得到不同的输出,依赖于你的编译器怎样表现它的name( )信息。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有