C++11类型转换总结

2023-11-04

一、强制类型转换

用C++中的四个强制类型转换的关键字:static_castconst_castreinterpret_castdynamic_cast

  • static_cast<类型说明符>(表达式)
  • dynamic_cast<类型说明符>(表达式)
  • const_cast<类型说明符>(表达式)
  • reinterpret_cast<类型说明符>(表达式)

1 static_cast

1.1 简介

static_cast相当于传统的C语言里的强制转换,任何具有明确定义的类型转换,只要不包括底层const,都可以使用static_const。

1.2 语法

用法为 static_cast<type-id> (expression)
  该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换的安全性

1.3 使用场景

    (1)用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
    (2)用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
    (3)把空指针转换成目标类型的空指针。
    (4)把任何类型的表达式转换成void类型。
 

1.4 举例 

char a = 'a';
int b = static_cast<char>(a);//正确,将char型数据转换成int型数据

double *c = new double;
void *d = static_cast<void*>(c);//正确,将double指针转换成void指针

int e = 10;
const int f = static_cast<const int>(e);//正确,将int型数据转换成const int型数据

const int g = 20;
int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

if(Derived *dp = static_cast<Derived *>(bp)){//下行转换是不安全的
  //使用dp指向的Derived对象  
}
else{
  //使用bp指向的Base对象  
}

if(Base*bp = static_cast<Derived *>(dp)){//上行转换是安全的
  //使用bp指向的Derived对象  
}
else{
  //使用dp指向的Base对象  
}

2 const_cast

2.1 简介

const_cast,用于修改类型的const或volatile属性。只要const_cast 能改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量属性都将引发编译器错误。

2.2 语法

const_cast < type-id > ( expression )

主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用

2.3 使用场景

该运算符用来修改类型的const(唯一有此能力的C++-style转型操作符)或volatile属性。除了const 或volatile修饰之外, new_type和expression的类型是一样的。

  • 常量指针被转化成非常量的指针,并且仍然指向原来的对象;
  • 常量引用被转换成非常量的引用,并且仍然指向原来的对象;
  • const_cast一般用于修改底指针。如const char *p形式。

2.4 举例

const int g = 20;
int *h = const_cast<int*>(&g);//去掉const常量const属性

const int g = 20;
int &h = const_cast<int &>(g);//去掉const引用const属性

 const char *g = "hello";
char *h = const_cast<char *>(g);//去掉const指针const属性

    const A *pca1 = new A;  
    A *pa2 = const_cast<A*>(pca1);  //常量对象转换为非常量对象  
    pa2->m_iNum = 200;    

错误用法:

常量对象(或基本类型)不可以被转换成非常量对象(或基本类型) 

 //常量对象被转换成非常量对象时出错
 const A ca;
 A a = const_cast<A>(ca);  //不允许

 const int i = 100;
 int j = const_cast<int>(i);  //不允许

使用const_cast去掉const属性,其实并不是真的改变原类类型(或基本类型)的const属性,它只是又提供了一个接口(指针或引用)。 

reinterpret_cast

3.1 简介

reinterpret_cast用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。

3.2 语法

new_type a = reinterpret_cast <new_type> (value)

将value的值转成new_type类型的值,a和value的值一模一样,比特位不变。

reinterpret_cast<xx>(yyy),xx与yyy必须有一个值为指针类型

3.3 使用场景

使用较少,且危险。

3.4 举例

int num = 0x00636261;//用16进制表示32位int,0x61是字符'a'的ASCII码
	int * pnum = &num;
	char * pstr = reinterpret_cast<char *>(pnum);
	cout<<"pnum指针的值: "<<pnum<<endl;
	cout<<"pstr指针的值: "<<static_cast<void *>(pstr)<<endl;//直接输出pstr会输出其指向的字符串,这里的类型转换是为了保证输出pstr的值
	cout<<"pnum指向的内容: "<<hex<<*pnum<<endl;
	cout<<"pstr指向的内容: "<<pstr<<endl;

 

 将pnum和pstr两个指针的值输出,两个指针的值是完全相同的,但是输出的内容不同,由于指针类型改变为 char * 导致的。

4 dynamic_cast

4.1 简介

           将基类的指针或引用安全地转换成派生类的指针或引用,并用派生类的指针或引用调用非虚函数。如果是基类指针或引用调用的是虚函数无需转换就能在运行时调用派生类的虚函数。

4.2 语法

dynamic_cast < type-id > ( expression)

该运算符把expression转换成type-id类型的对象。Type-id可以是类的指针类的引用或者void*。如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。

4.3 使用场景

4.4 举例

(1)向上转换:

class B { ... };
class C : public B { ... };
class D : public C { ... };
void f(D* pd)
{
   C* pc = dynamic_cast<C*>(pd);   // ok: C 是一个直接的基类
                                 // pc 指向 pd 的 C 子对象
   B* pb = dynamic_cast<B*>(pd);   // ok: B 是一个间接的基类
                                 // pb 指向 pd 的 B 子对象
   ...
}

(2)如果 type-id 是一个 void* ,运行时检查将决定表达式的实际类型。结果是一个到 expression 指向的完整对象 

class A { ... };
class B { ... };
void f()
{
   A* pa = new A;
   B* pb = new B;
   void* pv = dynamic_cast<void*>(pa);
   // pv 指向一个 A 类型的对象
   ...
   pv = dynamic_cast<void*>(pb);

   // pv 指向一个 B 类型的对象

}

如果 type-id 不是 void* ,运行时检查指向 expression 的对象能否转换为指向 type-id 类型的对象。

如果 expression 类型是 type-id 的基类,运行时检查是否 expression 实际是一个指向 type-id 类型的完整对象,如果是,结果返回指向 type-id 类型的完整对象,否则返回 NULL 。

5 沿用C的转换方式

C++是兼容C的,因此C语言中的强制类型转换在C++中同样适用,具体使用方法可以参照下面的代码示例:

float valueA = 3.0f;
int valueB = (int) valueA;

二、其他常见类型转换

2.1     const void *ptr 转换成 string类型

const char* ptrNew = (const char*)ptr; //强制转换为 char类型

std::string test(ptrNew,ptrNew.size());

2.2 string 转换为const char* ptr  

 string test="1233";

const char* ptr  = const_cast<char*>(test.c_str();

参考文献:

2.3 string与double类型互转

(1)double转换string

double d = 3.1415;
string str ="";
ostringstream os;
	if (os << d)
         str = os.str();

【1】C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_castC++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast - SpartacusIn21 - 博客园

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11类型转换总结 的相关文章

  • 检查空参数的最佳方法(保护子句)

    例如 您通常不希望构造函数中的参数为空 因此看到类似的内容是很正常的 if someArg null throw new ArgumentNullException nameof someArg if otherArg null throw
  • Unity3D StartCoroutine 调用一个函数,该函数什么时候返回?

    我知道Unity3D StartCoroutine调用了一个与StartCoroutine在同一线程上运行的函数 但是被调用的函数什么时候返回到原始调用者 我在互联网上查找了一个很好的 Unity3D Coroutine 示例 但找不到完整
  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • 没有 Unicode 字节顺序标记。无法切换到 Unicode

    我正在使用 XSD 编写 XML 验证器 下面是我所做的 但是当验证器到达该线时while list Read 它给了我错误 没有 Unicode 字节顺序标记 无法切换到 Unicode 有人可以帮我解决吗 public class Va
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • 在通过网络发送之前压缩位图

    我正在尝试通过网络发送位图屏幕截图 因此我需要在发送之前对其进行压缩 有一个库或方法可以做到这一点吗 当您将图像保存到流时 您have选择一种格式 几乎所有位图格式 bmp gif jpg png 都使用一种或多种压缩形式 因此 只需选择适
  • C 中的模仿函数重写

    具体来说 函数重写能够调用基本重写方法 这有两部分 一个是预编译的库代码 1 另一个是库的用户代码 2 我在这里实现了一个尽可能最小的经典 Person 和 Employee 示例 非常感谢了解 OOP 概念的铁杆 C 开发人员的回应 我正
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 线程安全的 C++ 堆栈

    我是 C 新手 正在编写一个多线程应用程序 不同的编写者将对象推入堆栈 读者将它们从堆栈中拉出 或至少将指针推入对象 C 中是否有任何内置结构可以在不添加锁定代码等的情况下处理此问题 如果没有 那么 Boost 库呢 EDIT 你好 感谢您
  • QThread - 使用槽 quit() 退出线程

    我想在线程完成运行时通知对象 但是 我无法让线程正确退出 我有以下代码 处理器 cpp thread new QThread tw new ThreadWorker connect tw SIGNAL updateStatus QStrin
  • 为什么重载方法在 ref 仅符合 CLS 方面有所不同

    公共语言规范对方法重载非常严格 仅允许根据其参数的数量和类型来重载方法 如果是泛型方法 则根据其泛型参数的数量进行重载 根据 csc 为什么此代码符合 CLS 无 CS3006 警告 using System assembly CLSCom
  • 是什么原因导致 Linq 错误:此方法无法转换为存储表达式?

    我有一堆具有相同 select 语句的 Linq to Entity 方法 所以我想我会很聪明 并将其分离到它自己的方法中以减少冗余 但是当我尝试运行代码时 我得到了以下内容错误 该方法不能转化为 商店表达式 这是我创建的方法 public
  • 有没有更好的方法来获取每个项目与谓词匹配的子序列?

    假设我有一个 IEnumerable 例如 2 1 42 0 9 6 5 3 8 我需要获得与谓词匹配的项目的 运行 例如 如果我的谓词是 bool isSmallerThanSix int number 我想得到以下输出 2 1 0 5
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 展开路径中具有环境变量的文件名

    最好的扩张方式是什么 MyPath filename txt to home user filename txt or MyPath filename txt to c Documents and settings user filenam
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 是否有任何不使用公共虚拟方法的正当理由? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何不使用公共虚拟方法的正当理由 我在某处读到我们应该避免使用公共虚拟方法 但我想向专家确认这是否是有效的声明 对于良好且稳定的 API
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源

随机推荐

  • 【完全开源】小安派-DSL 屏幕驱动开发板

    文章目录 概述 系统框图 2 8 3 5寸 屏电路 2 4寸触摸屏电路 1 28 寸圆形触摸屏电路 背光控制 关于Demo 1 28寸圆形屏智能手表Demo 2 4寸屏音乐播放器Demo 3 5寸屏天气站Demo 完全开源 概述 小安派 D
  • Altium Designer导入元器件3D封装

    一 前言 AD用了也有几年了 一开始只是单独用于制版 没有别的用途 随着工龄的增长 需求的内容也是越来越多 逐渐接触了3D模型建立 结构设计 有时需要导入PCB 3D效果 发现PCB导出的大多数只有芯片和电阻电容 很多开关 端子等特殊封装的
  • 前端开发利器: Bootstrap + AngularJS

    概述 在HTML5盛行的互联网时代 涌现诸多的前端html css js框架 基于其 适用范围 licence 发展前景等因素 本人对比总结出其中的两个佼佼者 分别是侧重页面美化展现的 Bootstrap 和侧重页面逻辑控制的 Angula
  • LeetCode题目笔记--2.两数相加

    这个博客系列记录我刷LeetCode过程中的一些循序渐进的思路和想法 希望能坚持下去 如果读者老爷觉得有帮助 就点个赞吧 题目描述 给出两个 非空 的链表用来表示两个非负的整数 其中 它们各自的位数是按照 逆序 的方式存储的 并且它们的每个
  • 数据导入hudi报错,错将字段写到hdfs路径上

    报错信息 Error trying to save partition metadata this is okay as long as atleast 1 of these succced file qiche hudi table 冬天
  • 2020无人用的邮箱和密码大全_Amazon后台登录密码错误!如何辨别账号是否被冻结?...

    啊你绝对不知道 这里每天都会更新一些跨境电商实时动态 卖家经验交流 跨境平台动态研究 曝光销售技巧 转化技巧 站外引流的方法 亚马逊后台登录密码错误 如何辨别账号是否被冻结 很多人一看到自己账号登录不进去就开始心慌 因为2018年就因为亚马
  • [QT编程系列-6]:C++图形用户界面编程,QT框架快速入门培训 - 3- QT窗体设计 - 自定义菜单栏

    目录 3 QT窗体设计 3 1 自定义菜单 3 1 1 设计目标 编辑 3 1 2 创建过程 编辑 3 QT窗体设计 3 1 自定义菜单 3 1 1 设计目标 3 1 2 创建过程 在Qt中 Windows窗口和Widget窗口是两种不同的
  • 如何用python加NLP打造自己的智能问答机器人

    一 基本流程 我们可以参照以下流程进行智能机器人的程序设计工作 1 利用已有的数据对 TfidfVectorizer 模型进行训练 2 利用训练好的TF IDF模型进行训练数据data0和真实数据data1的TFIDF值求解 3 通过余弦相
  • Spring Boot 3.x 构建系统&Starters

    系列文章目录 系列文章 Spring Boot 3 x 系列教程 文章目录 系列文章目录 前言 一 依赖管理 二 Maven 三 Spring Boot Maven Plugin 四 Starters 前言 Spring Boot 建议选择
  • c语言double类型的输入

    c语言double类型的输入 double输入用 lf 而不能用 f 今天在使用double类型输入时先用了 scanf lf a 结果以 f输出的时候都是0 以 g e输出似乎是最小的double值 12 3456789 0 000000
  • 软件产品设计

    figma软件介绍 Figma是一款在线协作式设计工具 用于 UI UX 设计和原型开发 它提供了一整套设计工具 包括向量绘图 页面布局和共享协作 支持多人协作 让用户可以在任何设备上创建 共享和讨论设计 知识点和技能 设计理论 理解UI设
  • Linux下xargs工具的使用

    xargs命令是给其他命令传递参数的一个过滤器 也是组合多个命令的一个工具 它能够将标准输入或管道中的数据转换为特定命令的命令行参数 也可以将单行或多行文本输入转换为其他格式的数据 比如单行变多行或者多行变单行 xargs的默认命令是ech
  • VS中的快捷键快速格式化代码,使好看,整齐

    在VC2005中 快捷键是Ctrl K Ctrl F 这是一个组合键 即先按Ctrl K 这时候编辑器会等待下一个按键动作 此时再按Ctrl F 即可以格式化代码了 当然 也可以在选项里面设置成使用VC6的快捷键 就可以继续使用Alt F8
  • 简述:面向对象的程序设计思想是什么?

    本博文源于C 基础 学到了类与对象这一章节 看见了课后有一个问题叫做 面向对象的程序设计思想是什么 我翻阅书籍 写下了这样一段话 就是警惕自己 如果未来被面试题面到 也能当做背诵个资料来看 下面开始简述那段话 文章目录 1 简述 面向对象的
  • PDM信号与PCM信号

    总结一下PDM信号与PCM信号 PDM PDM 脉冲密度调制 模拟信号的幅值使用输出脉冲对应区域的密度表示 PWM波是PDM波转换频率固定的一种特例 在实际输出的一位数据流中 只存在 1 和 0 1的密度越大 代表该区域对应的模拟信号幅值越
  • sql 2000 分页

    create PROCEDURE dbo Proc GetPageList Tables varchar 1000 表名 PK varchar 100 主键 Fields varchar 1000 查询的字段 SortField varch
  • 一阶RC滤波器

    一阶RC滤波器 作者 AirCity 2020 2 6 Aircity007 sina com 本文所有权归作者Aircity所有 RC低通滤波器 频响曲线 幅度下降到Ui 2 即是3dB带宽 此时 CR 1 2 f 1 CR f 1 2
  • SLF4J: Class path contains multiple SLF4J bindings.

    springboot启动出现如下警告 SLF4J Class path contains multiple SLF4J bindings SLF4J Found binding in jar file C Users wangfei m2
  • Python做数据分析需要学什么?

    下面分别从这四个方面来带大家学习数据分析 第一 做数据分析要精通Python吗 第二 数据分析流程是什么 学什么 第三 如何培养数据分析思维 第四 数据分析书籍推荐 一 数据分析要精通Python吗 做数据分析不必精通Python 但至少要
  • C++11类型转换总结

    一 强制类型转换 用C 中的四个强制类型转换的关键字 static cast const cast reinterpret cast dynamic cast static cast lt 类型说明符 gt 表达式 dynamic cast