C++四种常用的类型转换机制

    在C语言中,我们常常使用 (type)expression 这样的语句来把expression表达式强制转换为type类型的数据,而在c++中我们引用了四种类型转换操作符:const_cast,static_cast,dynamic_cast和reinterpret_cast;

1、static_cast 的威力和c语言的旧式转型有相同的效果和相同的限制;

2、dynamic_cast 将指向基类对象的指针或者引用转型为派生类(安全向下转型),并且在转型的过程中可以获知转型是否成功,对于指针,如果转型失败会返回一个null指针,如果是对引用转型失败,会抛出一个bad_cast异常,dynamic_cast通常情况下应该用于包含虚函数的类型上(因为dynamic_cast操作符属于运行时类型识别操作,所以我们需要虚函数表来记录类的继承关系,包括父类和派生类,只有在包含虚函数的情况下,编译器才会为对象维护一个虚函数表,所以应该必须包含一个虚函数的类型才能运用此操作符!);

    dynamic_cast  (e);   //指针转换

    dynamic_cast  (e);  //引用转换

上面的两个表达式必须符合以下三个条件中的任一个:e的类型是目标type的公有派生类、e的类型是目标type的公有基类或者e的类型就是目标type的类型。


3、reinterpret_cast 该强制转换操作符的转换结果几乎总是和编译平台相关,所以不具有移植性,其最常用于函数指针的转换,某些情况下这样的转型可能会导致不正确的结果,所以这种操作尽量别用。

4、const_cast  上面三种操作符都不能移除变量的const和 volatile的特性,只有该操作符能改变变量的这种特性;


可能出现的问题:

class A
{
    public:
        A(const int& i,const int& j)
        :x(i),y(j)
        {
        }
        void reset()
        {
            x += 10;
            y += 20;
        }
        void print()
        {
            cout<<"The x of the class A: "<(*this).reset();  //执行类型转换,然后重新设置参数,产生一个临时的对象,*this对象并没有变化
            //A::reset();    //得到结果与上面一行代码得到的结果不一样!!!
            //static_cast(this).reset();   //得到正确的结果
            z += 1;    
        }

        void print()
        {
            A::print();
            cout<<"The z of this B class is: "<
上面的可能出现问题的地方我已经用粗体标记出来了,所以当我们用到了类型强制转化的时候应该时刻警惕可能出现错误,导致程序得到一个“莫名其妙”的值:使用static_cast(*this).reset(); 得到的结果为:
C++四种常用的类型转换机制_第1张图片

通过输出我们可以发现,明明调用了reset()函数,却发现x,y的值并没有改变,只是z的值变化了;

当我们使用A::reset();函数时得到的结果如下:

C++四种常用的类型转换机制_第2张图片

可以发现x,y,z的值都变化了,因为当我们用强制转换的时候得到了(*this)对象的副本,改变的也是副本的值,所以最终打印*this对象的数据成员时并没有reset x,y的值,所以得到上述结果。

当我把static_cast(*this).reset()改为static_cast(this).reset();后通过指针的操作就可以得到正确的值,如下:

C++四种常用的类型转换机制_第3张图片

这进一步验证了改变的是*this对象副本的理论。






你可能感兴趣的:(c++)