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  <type*> (e);   //指针转换

    dynamic_cast  <type&> (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: "<<x<<endl;
            cout<<"The y of the class A: "<<y<<endl;
        }
    private:
        int x;
        int y;
};

class B : public A
{
    public:
        B(const int& i,const int& j,const int& k)
        :A(i,j)
        {
            z = k;
        }

        void reset()
        {
            static_cast<A>(*this).reset();  //<strong>执行类型转换,然后重新设置参数,产生一个临时的对象,*this对象并没有变化</strong>
            //A::reset();    //得到结果与上面一行代码得到的结果不一样!!!
            <span style="font-size:14px;">//<span style="font-size:14px;">static_cast<A*>(this).reset()</span></span>;   //得到正确的结果
            z += 1;    
        }

        void print()
        {
            A::print();
            cout<<"The z of this B class is: "<<z<<endl;
        }
    private:
        int z;
};
int main()
{
     B b(20,30,2);
     b.reset();
     b.print();
}

上面的可能出现问题的地方我已经用粗体标记出来了,所以当我们用到了类型强制转化的时候应该时刻警惕可能出现错误,导致程序得到一个“莫名其妙”的值:使用static_cast<A>(*this).reset(); 得到的结果为:

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

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

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

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


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






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值