zoukankan      html  css  js  c++  java
  • C++运算符之类型转换

    一、const_cast:只影响类型修饰符const,volatile
    用法:const_cast<type_id>(expression)

        该运算符用来修改类型的constvolatile属性。除了constvolatile修饰之外,type_idexpression的类型是一样的。

    • 常量指针被转化成非常量指针,并且仍然指向原来的对象;
    • 常量引用被转换成非常量引用,并且仍然指向原来的对象;
    • 常量对象被转换成非常量对象。
    二、static_cast
    • 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
    • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
    • 把空指针转换成目标类型的空指针。
    • 把任何类型的表达式转换成void类型。
    注意:static_cast不能转换掉expressionconstvolatile、或者__unaligned属性
    C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。

    三、reinterpret_cast:
    • 操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。
    • 所有映射中最危险的
    • static_cast和reinterpret_cast的区别主要在于多重继承,比如
    classA { public: int m_a;};
    classB { public: int m_b;};
    classC : public A, public B {};

    那么对于以下代码:

    C c;
    printf("%p,%p, %p\r\n", &c,             
                            reinterpret_cast<B*>(&c),
                            static_cast<B*>(&c)  );

    前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a, m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。


    四、dynamic_cast:

    • dynamic_cast运算符可以在执行期决定真正的类型。如果downcast是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果downcast不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。
    • 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
    • 进行向下类型转换时,必须是一个指向带有虚函数的类类型的指针。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表,只有定义了虚函数的类才有虚函数表。
    • 使用dynamic_cast要付出显著地运行开销和内存开销。 
    可以参考下面这个例子进行理解:
    Base b;
    00291A8B  lea         ecx,[b]  
    00291A8E  call        Base::Base (291131h)  
    Base* pb = NULL;
    00291A93  mov         dword ptr [pb],0  
    
    Derived d;
    00291A9A  lea         ecx,[d]  
    00291A9D  call        Derived::Derived (2911C7h)  
    Derived* pd = NULL;
    00291AA2  mov         dword ptr [pd],0  
    
    pb = &d;
    00291AA9  lea         eax,[d]  
    00291AAC  mov         dword ptr [pb],eax  
    pd = static_cast<Derived*>(pb);
    00291AAF  mov         eax,dword ptr [pb]  
    00291AB2  mov         dword ptr [pd],eax  
    
    pd = dynamic_cast<Derived*>(pb);
    00291AB5  push        0  
    00291AB7  push        offset Derived `RTTI Type Descriptor' (29A018h)  
    00291ABC  push        offset Base `RTTI Type Descriptor' (29A000h)  
    00291AC1  push        0  
    00291AC3  mov         eax,dword ptr [pb]  
    00291AC6  push        eax  
    00291AC7  call        @ILT+640(___RTDynamicCast) (291285h)  
    00291ACC  add         esp,14h  
    00291ACF  mov         dword ptr [pd],eax  
    



  • 相关阅读:
    Atitit attilax要工作研究的要素 纪要 方案 趋势 方向 概念 理论
    Atitit 常见每日流程日程日常工作.docx v7 r8f
    Atitit it 互联网 软件牛人的博客列表
    Atitit 信息链(Information Chain)的概念理解 attilax总结
    Atitit 知识点的体系化 框架与方法 如何了解 看待xxx
    Atitit 聚合搜索多个微博 attilax总结
    Atitit 企业知识管理PKM与PIM
    Atitit 项目沟通管理 Atitit 沟通之道 attilax著.docx
    Atitit 项目管理软件 在线服务 attilax总结 1. 项目管理协作的历史 1 1.1. Worktile 406k 1 1.2. Teambition  584k in baidu
    Atitit.每周末总结 于每周一计划日程表 流程表 v8 import 上周遗漏日志补充 检查话费 检查流量情况 Crm问候 Crm表total and 问候
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3000906.html
Copyright © 2011-2022 走看看