static_cast与dynamic_cast到底是什么?

简介: 该文讨论C++中`static_cast`和`dynamic_cast`在处理子类与父类指针转换的情况。总结如下:1. `static_cast`父类转子类:可能不安全,但不会报错。2. `static_cast`子类转父类:安全,无错误。3. `dynamic_cast`父类转子类:若父类有虚函数,运行时检查,成功返回子类指针,失败则为`nullptr`。4. `dynamic_cast`子类转父类:安全,无错误。

写这个随笔说一下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

}

输出:成功了。

相关文章
|
存储 前端开发 安全
前端安全性:常见攻击方式及防范措施
前端安全性是现代 Web 应用程序中不可忽视的重要方面。在网络环境中,前端代码容易受到各种攻击,比如 XSS(跨站脚本攻击)、CSRF(跨站请求伪造)、点击劫持等。为了保护用户的数据和确保应用程序的安全,开发者需要采取一系列防范措施。本文将介绍常见的前端安全攻击方式,并提供相应的防范措施。
1738 0
|
10月前
|
监控 API 开发工具
HarmonyOS Next的HiLog日志系统完全指南:从入门到精通
本文深入解析HarmonyOS Next的HiLog日志系统,涵盖日志级别、核心API、隐私保护与高级回调功能,助你从入门到精通掌握这一重要开发工具。
|
安全 编译器 C语言
【C++ 类型转换关键字 *_cast 】理解const_cast、reinterpret_cast、dynamic_cast和static_cast的用法
【C++ 类型转换关键字 *_cast 】理解const_cast、reinterpret_cast、dynamic_cast和static_cast的用法
809 0
|
存储 安全 Java
一天十道Java面试题----第二天(HashMap和hashTable的区别--------》sleep、wait、join)
这篇文章是关于Java面试的第二天笔记,涵盖了HashMap与HashTable的区别、ConcurrentHashMap的实现原理、IOC容器的实现方法、字节码的概念和作用、Java类加载器的类型、双亲委派模型、Java异常体系、GC如何判断对象可回收、线程的生命周期及状态,以及sleep、wait、join、yield的区别等十道面试题。
一天十道Java面试题----第二天(HashMap和hashTable的区别--------》sleep、wait、join)
|
安全 编译器 程序员
[C++ 从入门到精通] 6.static_cast、dynamic_cast等显示类型转换
[C++ 从入门到精通] 6.static_cast、dynamic_cast等显示类型转换
555 0
|
设计模式 Java 数据库连接
|
编译器 Ubuntu Windows
|
开发工具 git
【Git】报错解决cannot open .git/FETCH_HEAD: Permission denied
【Git】报错解决cannot open .git/FETCH_HEAD: Permission denied
1849 0
|
存储 数据采集 数据处理
Python filter函数
Python filter函数
Python filter函数
|
存储 算法 C++
【C++ 包装器类 map】C++ 标准库(std)中的map结构 哈希表(unordered_map)和黑红树(map)教程
【C++ 包装器类 map】C++ 标准库(std)中的map结构 哈希表(unordered_map)和黑红树(map)教程
1551 1