c语言强制转化的正确使用(c强制类型转换规则)

dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。

>>>>>>>>>>>编译器的RTTI设置>>>>>>>>>>>

dynamic_cast提供RTTI(Run-Time Type Information),也就是运行时类型识别。它对编译器有要求,需要编译器启动“运行时类型信息”这一选项。当编译器不开启RTTI时,运行含有dynamic_cast操作符的程序时会出现一个警告:

warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“ANIMAL”上;可能导致不可预知的行为

VS2010在默认下是开启RTTI的,也可以自己手动去开启或者关闭,操作如下:

视图->解决方案资源管理器

c语言强制转化的正确使用(c强制类型转换规则)

c语言强制转化的正确使用(c强制类型转换规则)

在前面的例子中,使用了dynamic_cast将基类指针转换为派生类指针,也可以使用dynamic_cast将基类引用转换为派生类引用。

同样的,引用的向上转换总是安全的:

    Derived c;    Derived & der2= c;    Base & base2= dynamic_cast<Base&>(der2);//向上转换,安全    base2.Show();

所以,在引用上,dynamic_cast依旧是常用于“安全的向下转型”。与指针一样,引用的向下转型也可以分为两种情况,与指针不同的是,并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常:

int main(){        //第一种情况,转换成功    Derived b ;    Base &base1= b;    Derived &der1 = dynamic_cast<Derived&>(base1);    cout<<"第一种情况:";    der1.Show();    cout<<endl;    //第二种情况    Base a ;    Base &base = a ;    cout<<"第二种情况:";    try{        Derived & der = dynamic_cast<Derived&>(base);    }    catch(bad_cast)                                                                             学习交流群:894479708                                                欢迎所有初学和进阶者一起讨论学习!                                    {        cout<<"转化失败,抛出bad_cast异常"<<endl;    }    system("pause");}

运行结果:

c语言强制转化的正确使用(c强制类型转换规则)

  • 使用dynamic_cast转换的Base类至少带有一个虚函数

当一个类中拥有至少一个虚函数的时候,编译器会为该类构建出一个虚函数表(virtual method table),虚函数表记录了虚函数的地址。如果该类派生了其他子类,且子类定义并实现了基类的虚函数,那么虚函数表会将该函数指向新的地址。虚表是C++多态实现的一个重要手段,也是dynamic_cast操作符转换能够进行的前提条件。当类没有虚函数表的时候(也即一个虚函数都没有定义),dynamic_cast无法使用RTTI,不能通过编译(个人猜想…有待验证)。

  当然,虚函数表的建立对效率是有一定影响的,构建虚函数表、由表查询函数 都需要时间和空间上的消耗。所以,除了必须声明virtual(对于一个多态基类而言),不要轻易使用virtual函数。对于虚函数的进一步了解,可以查看《Effective C++》

(0)
小多多的头像小多多创始人

相关推荐

发表回复

登录后才能评论