C++类型转换运算符dynamic_cast、static_cast 和 reinterpret_cast

news/2024/10/23 11:28:05/

目录

区别对比

dynamic_cast:

static_cast:

reinterpret_cast:

案例说明

dynamic_cast

static_cast

reinterpret_cast


C++ 中有三种主要的类型转换运算符:dynamic_caststatic_castreinterpret_cast。这些转换运算符可以用来在不同的上下文中进行类型转换,但它们的行为和使用场景是不同的。

区别对比

dynamic_cast

  • 用于在运行时检查继承关系
  • 只能用于具有多态性质的类,即必须有虚函数
  • 用于从一个基类指针或引用转换为派生类指针或引用
  • 会在运行时进行类型检查,如果无法完成类型转换,会返回 null 指针或抛出 std::bad_cast 异常

static_cast

  • 用于常见的隐式类型转换或明显的类型转换
  • 可以执行基本类型之间的转换,也可以执行非常量之间的转换
  • 可以执行多态类之间的指针和引用转换,但不会进行运行时类型检查
  • 可以执行 const 的添加或删除,以及 volatile 的添加或删除

reinterpret_cast

  • 用于执行不同类型之间的完全不同的转换
  • 可以将一个指针转换为一个整数,也可以将一个整数转换为一个指针
  • 没有进行任何运行时检查,因此可能会导致未定义的行为
  • 应该只在特定情况下使用,例如在硬件编程或底层实现中

案例说明

dynamic_cast

dynamic_cast主要用于类的多态转换,将父类指针或引用转换为子类指针或引用。如果转换成功,返回指向子类对象的指针或引用,否则返回空指针或引用。dynamic_cast只能用于含有虚函数的类之间的转换。

例如,有一个基类Animal和两个子类Dog和Cat:

class Animal {public:virtual ~Animal() {}
};
class Dog : public Animal {public:void bark() { std::cout << "Bark!" << std::endl; }
};
class Cat : public Animal {public:void meow() { std::cout << "Meow!" << std::endl; }
};

现在有一个Animal指针,指向一个Dog对象,我们可以使用dynamic_cast将其转换为Dog指针:

Animal* animal = new Dog();
Dog* dog = dynamic_cast<Dog*>(animal);
if (dog != nullptr) {dog->bark();
}

在这个例子中,由于animal指向的是Dog对象,所以dynamic_cast将其转换为Dog指针是安全的,转换后的指针可以调用Dog类中的成员函数bark()。如果animal指向的是Cat对象,那么dynamic_cast将返回空指针。

static_cast

static_cast主要用于静态类型转换,将一种数据类型转换为另一种数据类型。static_cast可以用于任何可以互相转换的数据类型,包括基本数据类型和自定义类型。在转换过程中,static_cast不进行运行时类型检查,因此可能会导致不安全的类型转换。

例如,将一个整数转换为浮点数:

int num = 10; 
double d = static_cast<double>(num);

在这个例子中,我们使用static_cast将一个整数转换为浮点数,转换后的结果保存在变量d中。

reinterpret_cast

reinterpret_cast主要用于指针或引用的类型转换,将一个指针或引用转换为另一个不同类型的指针或引用。reinterpret_cast不进行类型检查,因此可能会导致不安全的类型转换。由于这种转换可能会导致未定义的行为,因此应该谨慎使用reinterpret_cast。

例如,将一个整数的地址转换为字符指针:

int num = 65; 
char* ptr = reinterpret_cast<char*>(&num); 
std::cout << *ptr << std::endl;

在这个例子中,我们使用reinterpret_cast将一个整数的地址转换为字符指针,然后通过指针访问该地址上的字符值,输出结果为字符'A'。由于这种转换不安全,因此应该避免在实际开发中使用。


http://www.ppmy.cn/news/45350.html

相关文章

【C++】3. 缺省参数

文章目录 一、缺省参数的定义二、缺省参数的使用规则 一、缺省参数的定义 在c语言中&#xff0c;我们使用一个函数时&#xff0c;必须要传对应的参数&#xff0c;少一个都不可以。难道函数的参数就不能有个默认值吗&#xff1f;于是C对c做出了改良&#xff0c;创造了缺省参数。…

计数排序问题

文章目录 计数排序程序设计程序分析计数排序 【问题描述】有N个整数,用计数排序法排序 【输入形式】N个整数 【输出形式】N个整数 【样例输入】 10 2 1 4 2 3 3 3 2 9 5 【样例输出】 1 2 2 2 3 3 3 4 5 9 程序设计 C语言 #include<stdio.h> #include<string.h>…

AOP通知中获取数据

AOP通知中获取数据 之前我们写AOP仅仅是在原始方法前后追加一些操作&#xff0c;接下来我们要说说AOP中数据相关的内容&#xff0c;我们将从获取参数、获取返回值和获取异常三个方面来研究切入点的相关信息。 获取切入点方法的参数&#xff1a;所有的通知类型都可以获取参数 …

Node.js—path模块

目录 1、什么是path模块2、path.resolve 拼接规范的绝对路径 常用3、path.sep 获取操作系统的路径分隔符4、 path.parse 解析路径并返回对象5、path.basename 获取路径的基础名称6、path.dirname 获取路径的目录名7、path.extname 获得路径的扩展名8、 path.join()路径拼接 1、…

在windows上安装部署cicd

安装步骤 下载gitlab-runner&#xff0c;官网地址如下&#xff1a; https://docs.gitlab.com/runner/install/windows.html在任意位置创建文件夹&#xff0c;并把安装程序放入文件夹中 安装gitlab-runner 注意需要使用管理员权限&#xff0c;打开powershell才能运行 cd C:\Gi…

Android Binder 图文解释和驱动源码分析

前言 最近在学习Binder&#xff0c;之前都是跳过相关细节&#xff0c;通过阅读文章对Binder有了一些认识&#xff0c;但是并没有真正理解Binder。如果要深入理解Framework的代码&#xff0c;就必须要真正理解Binder。 我学习Binder的方法&#xff1a; 一边阅读Gityuan的Bind…

002 学习鸿蒙应用开发ArkTs语言

目录 一.ArkTs语言介绍 1.ArkTs语言概述 2.ArkTs语言特性 二.基本UI描述 1.基本概念 2.UI描述规范 无参数构造配置 有参数构造配置 属性配置 事件配置 子组件配置 三.状态管理 1.基本概念 2.页面级状态管理 State Prop Link Observed和ObjectLink数据管理 P…

《3-链表》

链表 引言&#xff1a; 存储数组需要内存空间连续&#xff0c;当我们需要申请一个很大的数组时&#xff0c;系统不一定存在这么大的连续内存空间。 而链表则更加灵活&#xff0c;不需要内存是连续的&#xff0c;只要剩余内存空间大小够用即可 1.定义 &#xff1a; 「链表 Lin…