写这个随笔说一下C++的static_cast和dynamic_cast用在子类与父类的指针转换时的一些事宜。首先,【static_cast,dynamic_cast】【父类指针,子类指针】,两两一组,共有4种组合:用 static_cast 父类转子类、用 static_cast 子类转父类、使用 dynamic_cast 父类转子类、用 dynamic_cast 子类转父类。搞清楚了这4种情况,这篇文章的任务也就达成了。
先说结论,后面给出一个作者觉得通俗易懂的理解:
1. static_cast : 父类转子类:可以转,不报错,不安全;
2.static_casrt : 子类转父类:可以转,不报错,安全;
3.dynamic_cast : 父类转子类 :
a)若父类中没有虚函数,不能转,编译报错;
b)若父类至少有一个虚函数则可以转,不报错;但:
b.1)若父类指针指向的确实是一个子类对象,则dynamic_cast返回该子类对象的地址;
b.2)若父类指针指向的是父类对象,则dynamic_cast返回空指针nullptr;
4.dynamic_cast:子类转父类:可以转,不报错,安全。
总体来看,子类指针转成父类指针无论怎样都是安全、允许的(上面的2、4),所以static_cast和dynamic_cast都可以安全使用。
再说上面的1、3。 其实,static_cast相当于我们程序员对编译器的一种承诺:我们清楚地知道这样转存在的任何风险,并且我们能够接受这样的风险。所以,当我们用static_cast将父类指针转换成子类指针时,编译器不报错。而dynamic_cast是在运行时执行类型转换,用于将基类的指针安全地转换成派生类的指针,也就是说,dynamic_cast会进行动态类型检查。dynamic_cast相当于给程序员提供了一种安全的机制,让程序员能够安全地使用父类指针的动态类型。
下面举一个使用dynamic_cast(以上3中的b)的例子。首先给出父类和子类的定义:
class B { public: virtual ~B() {}; }; class D : public B { };
若有以上类的定义:
代码1:
B* pb = new B; if( D* p3 = dynamic_cast<D*>(pb) ) { cout << "成功了" << endl; //若程序到此处,则程序员知道,pb指向的实际上是子类对象,可以使用p3 } else { cout << "失败了" << endl; //若程序到此处,则程序员知道,pb指向的实际上是父类对象,使用pb }
输出:失败了。因为动态运行时,pb指向的是父类,并不是子类。
代码2:
B* pb = new D; if( D* p3 = dynamic_cast<D*>(pb) ) { cout << "成功了" << endl; //若程序到此处,则程序员知道,pb指向的实际上是子类对象,可以使用p3 } else { cout << "失败了" << endl; //若程序到此处,则程序员知道,pb指向的实际上是父类对象,使用pb }
输出:成功了。
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容