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类型转换总结 的相关文章

  • 将 System.Drawing.Image 转换为 System.Windows.Media.ImageSource 但没有结果

    我想在我的 WPF 应用程序中将 Image 转换为 ImageSource 我使用正常工作的 Code128 库 已在 WinForms 应用程序中检查 下面的函数返回具有适当大小的 ImageSource 但没有任何内容可见 priva
  • 如何查找boost运行时版本

    我正在编写一个使用 boost 的 C 库 在这个库中 我想包含有关用于编译我的库的二进制版本的 boost 版本的信息 我可以使用宏BOOST VERSION这很好 我还想确定哪个是 boost 的运行时版本 以便我可以与用于编译我的库的
  • 加权 Voronoi 的 CGAL 2D APOLLONIUS 图 - 如何生成和获取面和顶点?

    我正在尝试根据阿波罗尼乌斯图生成加权沃罗诺伊 我正在使用 CGAL 库 我找不到如何从 apollonius 获取面和顶点的好例子 我有以下类型定义 typedef double NT typedef CGAL Cartesian lt N
  • 每个 CPU 核心处于 C0 电源状态的时间

    任何帮助弄清楚如何做到这一点都会很棒 在过去一秒内 每个 CPU 核心处于 C0 电源状态的时间有多少 这是针对 Mac 应用程序的 因此需要 Objective C cocoa 和 c OS X 没有任何公开 CPU c 状态的 API
  • 将数组从 C# 编组到 C++ 并返回:PInvokeStackImbalance

    我有一个 C 函数 我想从 C 访问它 问题是我不断收到 PInvokeStackImbalance 异常 但我不知道为什么 当检查异常被关闭时 一切都运行良好并且符合预期 我的 C 函数的签名是 extern C double solve
  • 线程安全的get(访问器方法)

    我目前正在使用以下代码对变量进行线程安全访问 int gnVariable void getVariableValue int pnValue acquireLock Acquires the protection mechanism pn
  • VBA 中的 VSTO:AddIn.Object 有时不返回任何内容 (null)

    Given VSTO 插件 An override object RequestComAddInAutomationService 它返回一个名为的类的实例Facade在我的场景中 Excel 2007 中的 VBA 宏可访问AddIn O
  • c#Registry to XML无效字符问题

    我在尝试从注册表创建 XML 文件时遇到问题 在我的笔记本电脑 W7 64b 上它工作正常 生成了 xml 文件 但在另一台计算机 Xp 32b 上抛出异常 System ArgumentException 十六进制值 0x00 是无效字符
  • 从空白启动时 VSTO 功能区不显示解决方案

    如果我从 文件 新建项目 菜单创建一个新的 Excel 2013 和 2016 VSTO 加载项 项目 然后单击 项目 添加新项目 gt 功能区 可视化设计器 则一切正常 我启动了应用程序 我的功能区显示在 Excel 中 但是 如果我首先
  • 是否可以用 C# 为 Android 编写应用程序?

    我们都知道Android运行Dalvik VM程序 通常开发人员用 Java 编写程序并将其编译为 Dalvik 字节码 我想知道是否有可能创建一个可以接受 C 代码并将其编译为 Dalvik 字节码的编译器 嗯 这是一种选择 或者您可以在
  • popen2()在c中如何工作?

    我尝试使用管道 叉子和 dup 在我的程序中执行 md5sume 命令 我发现总和代码运行成功 但我无法理解某些代码行 这是我的代码 int infp outfp char buf 128 if popen2 md5sum infp out
  • 使用经度和纬度查找给定距离内的所有附近客户

    我有一个包含客户经度和纬度的数据库 我有一个搜索表单 用户将在其中输入日志 纬度 距离下拉列表包含 50 英里 100 英里 当用户单击搜索时 我想编写一个 linq 查询从数据库中获取此距离半径内的所有客户 如何使用 C 和 linq 来
  • 发生错误。", ExceptionMessage: "提供的 'HttpContent' 实例无效

    尝试将文件添加到 http 休息调用时出现此错误 responseJson 消息 发生错误 ExceptionMessage 提供了无效的 HttpContent 实例 它确实 正在使用 多部分 参数名称 内容 异常类型 System Ar
  • 使用 cryptoapi CryptImportKey 导入公钥时出错

    我想将公钥 blob 导入到 CSP 但发生了错误 BYTE pbData 0xEB 0x2A 0x38 0x56 0x86 0x61 0x88 0x7F 0xA1 0x80 0xBD 0xDB 0x5C 0xAB 0xD5 0xF2 0x
  • 允许 .NET WebApi 忽略 DOCTYPE 声明

    我正在尝试通过 WebApi 方法将 XML 反序列化为对象 我有以下课程 XmlRoot IsNullable false public class MyObject XmlElement Name public string Name
  • 专家 C#/.Net/WPF 开发人员应该了解哪些知识? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 修改公共属性的访问修饰符是否是重大更改?

    如果我将公共属性的 setter 的访问修饰符从私有更改为公共 是否会导致引用它的其他程序集发生任何重大更改 UPDATE 这个问题是我 2012 年 1 月博客的主题 https ericlippert com 2012 01 09 ev
  • #define, #ifdef #undef #endif

    我有以下代码 define PROC ADD void main void while 1 ifdef PROC ADD Do this code here then undefined it to run the code in the
  • 如何从标准输入读取一行,阻塞直到找到换行符?

    我试图从命令行的标准输入一次读取任意长度的一行 我不确定是否能够包含 GNU readline 并且更喜欢使用库函数 我读过的文档表明getline应该可以工作 但在我的实验中它不会阻塞 我的示例程序 include
  • jquery ajax“发布”调用

    我是 jQuery 和 Ajax 的新手 并且在 发布 方面遇到问题 我正在使用 jQuery Ajax post 调用将数据保存到数据库 当我尝试保存数据时 它将 null 传递给我的 C 方法 jQuery 看起来像这样 functio

随机推荐

  • 【完全开源】小安派-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