c++显示类型转换

来源:互联网 发布:青年网络公开课印度 编辑:程序博客网 时间:2024/05/17 08:28

由于c++有多重继承甚至是虚基类,所以提供一套显示的类型转换有助于提高代码质量,也容易阅读。其中最有有用的自然是dynamic_cast,但需要rtti的支持(typeid也是一样)。其余有const_cast reinterpret_cast , static_cast,其实除了dynamic_cast中把基类指针和引用专程子类指针和引用时需要判断此基类指针是否指向子类外,其他的显示转换都可以用C中的隐式转换完成。

1.dynamic_cast<type>: type只能是指针和引用类型,且必须指向用户自定义的多态对象。其余类型比如int int * int &等内建类型都会导致编译出错。多用于download casting,即基类往子类转换。事实上在没有打开RTTI的情况下,dynamic_cast是没有任何作用的,因为无法从vptr所指向的内存块中获取运行信息。

2.const_cast: 去掉对象的 const volatile _unaligned属性。但应用于内建类型,下面的情况被编译器优化掉。如

const int a=10;const_cast<int &>(a)=9;cout<<a<<endl;//结果仍可能是10,虽然a的值已经是9了。因为编译器直接使用10。如果const int a=bb,就不会被优化掉了。其实const_cast并不是让你对基本类型的转换,而是用于const成员函数中需要改变某个成员变量的值,对this指针进行暂时的转换。

3.static_cast: 适用于任何类型,但对于download casting它是不安全的。

4.reinterpret_cast: 最原始的转换,从指针到指针,从指针到整型或者相反。它全然不顾类之间的继承关系,只是改变变量的类型而从不改变变量的值。其实就是c中的强制转换(int)   (int *)

class A{

public:

virtual ~A(){}

};

class B{

public:

virtual ~B(){}

};

class D: public A, public B{

public:

void f(){}

virtual ~D(){}

};

B* b = new D();//隐式转换,假设对象d的首地址为 0x******2

   D *d = dynamic_cast<D*>(b)//显示转换,如果 b确实是指向D的对象,那么等同于 d=b或者d = static_cast<D*>(b),

cout<<reinterpret_cast<int>(b)<<reinterpret_cast<int>(d)//结果为 0x*****2 , 0x*******6

d = b;

cout<<reinterpret_cast<int>(static_cast<D*>(b))<<reinterpret_cast<int>(d)//结果为 0x*****2 , 0x*******6

如果b只是指向基类的指针,那么dynamic_cast将返回NULL,其他都将返回经过计算后的指针值。

B *b = new B();//B对象的首地址为 0x*******2

cout<<reinterpret_cast<int>(static_cast<D*>(b))<<reinterpret_cast<int>(dynamic_cast<D*>(b))//结果为 0x*****6 , 0x0000000

 

const D d;

d.f();//编译错误,f不是const函数

const_cast<D &>(d).f()//可以顺利执行

当你要在const成员函数中改变对象的成员变量时,可以使用 const_cast<Object *>(this)->a=1;

当然也可以用传统的方法 ((Object * ) this )->a=1;

       当 把基类指针转换成子类指针时你可能不知道此基类指针是否真的是指向子类对象的,这是必须用dynamic_cast来动态检验外。其余转换都有可以有传统方法解决。无论使用传统的方法还是这些显示的方法 ,最重要的是掌握类层次结构,了解c++是如何运作的。这就是c++的尴尬之处,它提供了面向对象的机制,但确让你对这些机制十分了解之后才能使用,不然错误百出。不像java,你什么都不用管,只要专注于软件设计就行了。

      下面是linus激烈批评某位仁兄,因为此仁兄建议linus用c++去写git,linus言词之激烈到了失礼的地步,文章开篇就是 *YOU* are full of bullshit.

还有一句 Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out。

加*和加粗是linus加的,可见他已经到了发狂的地步。。。。。

原创粉丝点击