7.3 执行期类型识别(Runtime Type Identification,RTTI)

本文探讨了C++中安全的基类到派生类的向下转换操作,介绍了dynamic_cast运算符如何在运行时确定对象的真实类型以确保类型转换的安全性,并分析了dynamic_cast在指针和引用上的不同表现。此外,还讲解了typeid运算符的用法及其返回的type_info对象支持的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Q1:保证安全的基类到派生类的向下转换操作

• 支持安全的类型转换对多态类而言,需要在执行期判断指针所指对象的真实类型,因此,会引入额外的空间与时间开销:

    ○ 空间开销:存储类型信息,通常是一个指针,指向某个类型信息的节点(该指针放置在虚函数表的第一个表项中)
    ○ 时间开销:在执行其决定其类型

• 区别一个类是否具有多态性,是根据其是否内含虚函数来进行判断。(注:析构函数是唯一不能重载的成员函数)



Q2:保证安全的动态转换

• dynamic_cast 运算符可以在执行期决定真正的类型,对指针对象而言,如果该操作是安全的,就会传回被适当转换过的指针,如果不安全,就传回0

• 考虑 dynamic_cast 的真正成本

Eg:

            //class B : public A{};

            void example(A * ap)
            {
                if(B * bp = dynamic_cast<B*>(ap))
                    {//…}
                else
                    {//…}
            }

以上式为例,编译器会为 B* 产生一个类型描述器,并通过 ap 所指类对象的类型则通过 vptr 取得,取得方式如下:

            ((type_info*)(ap->vptr[0]))->_type_descriptor;      //取得 ap 所指类对象的类型描述器

type_info 是 C++ 标准定义的类型描述器的类名称,通过 vptr 取得 ap 所指对象的类型描述器,将两个类型描述器进行比较,即可判断该转换是否安全



Q3:引用并不是指针

• 对一个类指针施行 dynamic_cast ,会获得该指针值或者0:

    • 如果传回指针,表示该转换操作安全
    • 如果传回0,表示该转换错误。0表示该指针并未指向任何对象

• 对引用而言,不能对一个引用赋值为0,表示其并未引用任何对象!!!!因为当将 0 赋值给引用对象时,将会产生一个临时对象,该对象的初值是0,该引用会被设为此临时对象的别名。

• 对一个引用施行 dynamic_cast,会成功或者抛出一个 bad_cast 异常:

    • 若未抛出异常,则引用转换操作安全
    • 若抛出异常,则该引用转换不安全

• 合适的引用转换操作例子。将上述程序例子改为:

Eg:

        void example(A & a)
        {
            try{
                B & b = dynamic_cast<B&>(a);
            }
            catch (bad_cast b)
            {
                //…
            }       
        }



Q4:Typeid 运算符

• typeid运算符传回一个 const reference,其类型为 type_info

• type_info 类对象支持的操作:==,!=,before(),name(),VS 还提供(raw_name())

• type_info 的默认构造函数,复制构造函数,赋值操作符函数均是私有函数,因此, type_info 对象不支持复制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值