大家都来指导指导,由boost里面的使用typeid操作符引出的我的问题.

jiangwentao 2003-11-11 12:13:43
这两天看了一下boost的代码,在boost::any的代码里面看到了操作符typeid,typeid使我第一个想到了RTTI,我不喜欢RTTI,我对RTTI内部知道很少,到现在我一直认为RTTI在程序里面每一个出现的有vTable的类都要加上额外信息而有些类根本不需要这些RunTime信息,所以没什么库用RTTI,要runtime也自己写.
boost怎么会用RTTI机制呢,是我那里错了吧,带着问题我又学习了一下c++的相关内容,发现这些地方我都没有搞清楚.

1 catch块需要RTTI么?

如下测试程序:

#include "stdafx.h"
#include "stdio.h"

class aaa
{};

class bbb
{public :virtual ~bbb(){};};

int main(int argc, char* argv[])
{
try
{ throw 5; }
catch (int val) { printf("\nint"); }
catch (double val) { printf("\ndouble");}
catch(char val) { printf("\nchar");}

try
{ throw aaa(); }
catch (int val) { printf("\nint"); }
catch (double val) { printf("\ndouble");}
catch(char val) { printf("\nchar");}
catch(aaa val) { printf("\ntype aaa");}
catch(bbb val) { printf("\ntype bbb");}

try
{ throw bbb(); }
catch (int val) { printf("\nint"); }
catch (double val) { printf("\ndouble");}
catch(char val) { printf("\nchar");}
catch(aaa val) { printf("\ntype aaa");}
catch(bbb val) { printf("\ntype bbb");}

return 0;
}

msvc60编译器编译通过并不需要在project seting中复选上Enable Run-Time Type Information[RTTI] 复选框.
可见好像没有C++的RTTI机制代码参与程序的运行, 可是catch块捕获异常是对异常类型的判断毫无疑问的是runTime的.???????

2 typeid 需要 RTTI支持么?

class aaa
{};

class bbb:public aaa
{};


void main()
{
aaa one,two;
bbb three;
if(typeid(one)==typeid(two)){printf("\n ok");}
if(typeid(one)==typeid(three)){printf("\n ok");}
aaa *p1=NULL;
const type_info& ty11=typeid(p1);
printf("\n%s",ty11.name());
const type_info& ty12=typeid(*p1);
printf("\n%s",ty12.name());

bbb *p2=(bbb*)p1;
const type_info& ty21=typeid(p2);
printf("\n%s",ty21.name());
const type_info& ty22=typeid(*p2);
printf("\n%s",ty22.name());

}
msvc60编译器编译通过并不需要在project seting中复选上Enable Run-Time Type Information[RTTI] 复选框.

如果把类bbb改一下,给它一个vtble
class bbb:public aaa
{public :virtual ~bbb(){};};
则msvc60编译器要求RTTI机制

typeid操作符返回的结果是 在编译期就已经确定下来的,还是 一部分结果在编译器就确定下来另一部分结果确需要到运行期确定(需要RTTI),我这里觉得是第二个答案.

问题又有了,typeid操作符编译器是在什么情况下决定用RTTI机制
在运行期返回结果呢?谁来给我一个相关的条文标准.
...全文
77 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
stkane 2003-12-05
  • 打赏
  • 举报
回复
我的一些经验:

首先,RTTI不仅包括typeid,还包括了象dynamic_cast等一些方法.

其次,RTTI似乎在处理多态的时候用的比较多.例如
有一个系列类,其层次如下:

CObject-->CDataObject->CInteger
|
-->CNullObject
|
-->CContainer->CStack
|
...

进场需要进行两个对象的比较,因此,在CObject中声明了如下函数
int Compare(CObject&) const;
那么显然,在进行比较的时候,传入的参数仅仅是CObject,而进行比较之前,首先要保证所比较的是统一类型的对象,比如都是CInteger,或者都是CStack.而不希望将一个CStack和一个CInteger进行比较.这时候就需要用typeid来确定类型.
另一方面,很可能定义一个类专门用于对CObject对象进行访问,比如定义
class CVisitor;
这个类的作为基类经常是抽象的.假设从它派生出子类:
class CSomeVisitor:public CVisitor
{
...
};
当然希望CSomeVisitor除了实现CVisitor的功能之外,还新增一些更强的功能,比如新增了下面的函数:
void CMethodPlus() const;
然而,在使用的时候,在CObject的所有派生类中,对于CSomeVisitor的接受,并不是按照:
void CObject::Accept(CSomeVisitor&);
而很可能是按照:
void CObject::Accept(CVisitor&);
这样在
void CObject::Accept(CVisitor&);
这个函数中,就希望能够知道CVisitor是不是CSomeVisitor,如果是那就可以使用
void CMethodPlus() const;
了.
这种情况RTTI提供了一种转化的检验制--通过dynamic_cast<TYPE>,比如
CSomeVisitor & rSomeVisitor=dynamic_cast<CSomeVisitor &>(rVisitor);
......


有一种观点认为,RTTI是完全不必要的,但是我个人认为,RTTI在有些场合下似乎是必需的.也许这个和一个人的编程风格有关.
fierygnu 2003-12-05
  • 打赏
  • 举报
回复
1、EH的实现主要工作是stack-winding。stack-winding的方法有很多,不一定要依赖RTTI,因为stack自身就是一个存储区,可以保存很多的信息。MFC的实现就是这样,参见:http://www.codeproject.com/cpp/exceptionhandler.asp
2、不是多态类时,RTTI不需要打开,因为这时所有的信息都是编译时可确定的,typeid也可以在编译时被确定,不需要运行时支持。
hpho 2003-11-21
  • 打赏
  • 举报
回复
我觉得楼主基本都分析出来了.
1, 内建类型不需要真正启动RTTI.
2, 只有是多态类的时候RTTI才会有效.

记得<Inside The C++ Object Model>最后一章有说这方面的东东
电视人 2003-11-21
  • 打赏
  • 举报
回复
看不出boost::any在编译期绑定了类型信。。。。。。。。。。。。
noirchloe 2003-11-14
  • 打赏
  • 举报
回复
typeid需要RTTI,其实他就是用RTTI实现的。而异常也是又RTTI实现的,所以catch等都需要有RTTI信息
以上仅供参考........
jiangwentao 2003-11-13
  • 打赏
  • 举报
回复
我怀疑throw语句编译器不仅抛出值暗地里面还要抛出类型信息(编译器已定).catch先进行类型信息比较
jiangwentao 2003-11-12
  • 打赏
  • 举报
回复
对,boost::any用不着RTTI,编译期都能搞定typeid.
短歌如风 2003-11-12
  • 打赏
  • 举报
回复
exception不需要使用的RTTI,它通过另一种方式来确定excpetion的类型。
typeid有不同的应用情况,当需要在给出一个基类指针类型变量时用typeid得到衍生类的真正类型时可能需要RTTI。

运行时的类型信息不只是RTTI独有的特性,多态本身就有这个性质。
jiangwentao 2003-11-11
  • 打赏
  • 举报
回复
typeid这个操作符好像一般的书都是一笔带过
wingfiring 2003-11-11
  • 打赏
  • 举报
回复
我猜测,如果能够在编译期间分析出类型信息,就不一定要RTTI。反之,就需要。
jiangwentao 2003-11-11
  • 打赏
  • 举报
回复
为啥没人看

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧