C++的类型转换

这篇具有很好参考价值的文章主要介绍了C++的类型转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. C语言的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就会发生类型转化
C语言总共有两种形式的类型转换:隐式类型转换显示类型转换(强制类型转化)

  1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
  2. 显示类型转化:需要用户自己指定
void Test ()
{
     int i = 1;
     // 隐式类型转换
     double d = i;
     
     int* p = &i;
     // 显示的强制类型转换
     int address = (int) p;
}

缺陷:
转换的可视性比较差,所有的转换形式都是相同形式书写,难以跟踪错误的转换

二. C++的四种类型转换

C语言风格的转换格式很简单,但是也有缺点:

  1. 隐式类型转化可能出现精度丢失,截断等问题
  2. 显示类型转换将所有情况混合在一起,代码不够清晰

因此C++提出了自己的类型转换风格,引入了四种命名的强制类型转换操作符
static_castreinterpret_castconst_castdynamic_cast

1. static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,即可用于意义相近的类型转换

void test1()
{
	double a = 12.34;
	//都是表述数值
	int b = static_cast<int>(a);
	cout << b << endl;
}

2. reinterpret_cast

reinterpret(重新解释),该操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型

void test2()
{
	double a = 12.34;
	//都是表述数值
	int b = static_cast<int>(a);
	//数值转换成地址
	int*p = reinterpret_cast<int*>(b);
}

3. const_cast

const_cast最常用的用途就是删除变量的const属性,方便赋值

void test3()
{
	const int a = 2;
	//删除const属性
	int *p = const_cast<int*>(&a);
	*p = 3;
	cout << *p << endl;
}

C++的类型转换,C++学习笔记,c++,java,jvm

4. dynamic_cast

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针/引用(动态转换)

向上转型:子类指针/引用–>父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类指针/引用–>子类指针/引用(用dynamic_cast转是安全的)

注意:

  1. dynamic_cast 只能用于父类含有虚函数的类
  2. dynamic_cast会先检查是否转换成功,能成功则转换,不能则返回0

为什么说向下转型用dynamic_cast是安全的,强制转换为什么不安全?

比如这样一个继承体系

class A
{
public:
	virtual void fun()
	{}
private:
	int _x;
};

class B :public A
{
private:
	int _y;
	int _z;
};

B继承A,但B拥有自己的成员变量,如果强制类型转换,情况如下:

C++的类型转换,C++学习笔记,c++,java,jvm

因为B比A大,所以B的指针能访问的空间更多,但是这部分并不属于A。如果原先是指向A类型对象的指针,那么强转成B类型的指针,访问权限变大,但那部分并不属于A类型对象,这就会造成越界

强制类型转换并不会管原先指向的到底是父类对象还是子类对象,都会转换成功。
而dynamic_cast会检查,如果是原先是父类对象,则转换失败返回0,如果是子类对象,则转换成功。

void fun(A* pa,const string&str)
{
	// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
	cout << str << "转换" << endl;
	B* pb1 = (B*)(pa);
	B* pb2 = dynamic_cast<B*>(pa);
	cout << "pb1:" << pb1 << endl;
	cout << "pb2:" << pb2 << endl << endl;
}

void test4()
{
	A a;
	B b;
	fun(&a,"父类对象");
	fun(&b,"子类对象");
}

C++的类型转换,C++学习笔记,c++,java,jvm

可以看到,强制转换不管父类还是子类对象都会发生转换,而dynamic_cast只有原先指向子类时才会发生转换

注意:
强制类型转换关闭或者挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方式达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。
强烈建议:避免使用强制类型转换

三. RTTI

RTTI:Run-time Type identification的简称,即:运行时类型识别

有以下三种方式:

  1. typeid:通过name()函数获取类型名称的字符串
    C++的类型转换,C++学习笔记,c++,java,jvm

  2. dynamic_cast:可以识别一个指针/引用,指向的是父类对象还是子类对象

  3. decltype:自动类型推导
    和auto类似,但是decltype是通过其他对象获取类型

auto x=1;//auto通过=号右边推导
decltype(x) y=1;//decltype通过x推导

auto要求变量必须初始化,因为auto根据变量的初始值来推导变量类型,如果不初始化,变量的类型就无法推导。
而decltype不需要初始化,所以decltype可以适用于只要自动推导类型的场景

比如如下场景:

function<int> add=[](int a,int b)->int{ return a+b; };
set<int,decltype(add)> s;

结束语

感谢你的阅读

如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
C++的类型转换,C++学习笔记,c++,java,jvm文章来源地址https://www.toymoban.com/news/detail-599767.html

到了这里,关于C++的类型转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java核心知识点1-java和c++区别、隐式和显示类型转换

    java和c++区别 java通过虚拟机实现跨平台特性,但c++依赖于特定的平台。 java没有指针,它的引用可以理解为安全指针,而c++和c一样具有指针。 java支持自动垃圾回收,而c++需要手动回收。 java不支持多重继承,只能通过实现多个接口来达到相同目的,而c++支持多继承。  隐式(

    2024年02月03日
    浏览(35)
  • Python学习笔记(2)--字面量,注释,变量,数据类型,数据类型转换,标识符,运算符

    传送门==B站黑马python入门教程 1.字面量 字面量 : 代码中被固定写的值 python常用的6种数据类型为 数字,字符串,列表,元组,集合,字典 目前基础部分学习 字符串,整数,浮点数 即可 字符串 :(文本),由任意数量的 字符 (示例:中文/英文/各类符号/数组)组成; 在 python 中,字符串需要用双

    2024年02月11日
    浏览(46)
  • python教程 入门学习笔记 第6天 数据类型转换 字符串转换成数值 数值之间互转 其它类型转字符串

    s1=\\\"188\\\" #字符串 ns1=int(s1) #转换成整型数值 print(ns1+8) #打印数值结果 s1=\\\"3.14\\\" #字符串 ns1=float(s1) #转换成浮点型数值 print(ns1+3) #打印数值结果(数值结果为6.140000000000001,出现误差,后面讲解决办法) print(type(ns1)) #获取新数值的数据类型属性 z1=78 nz1=float(z1) print(nz1) #打印结果

    2024年02月14日
    浏览(54)
  • Qt-OpenCV学习笔记--基本函数操作--cv::convertTo(图像类型转换)

    不是所有格式的Mat型数据都能被使用。 目前OpenCV主要只支持单通道和3通道的图像,并且此时要求其深度为8bit和16bit无符号(即CV_16U),所以其他一些数据类型是不支持的,比如说float型等。 如果Mat类型数据的深度和通道数不满足上面的要求,则需要使用convertTo()函数和cvtColor(

    2024年02月04日
    浏览(37)
  • 初学opencv c++学习笔记(二)图像空间色彩转换cvtColor()

    对图像的色彩转换用到cvtColor()函数,本章将对此其用法进行解析。 目录 一、色彩空间转换 官方定义  函数参数解释 代码演示 RGB——HSV  RGB——GRAY  BGR——RGB 总结 提示:以下是本篇文章正文内容,下面案例可供参考 APL:cvtColor() 1. src (source):输入的源图像。为矩阵形式。

    2024年02月05日
    浏览(34)
  • UE5 C++学习笔记 FString FName FText相互转换

    1.FString 是UE里的String。最接近std::string, 唯一可以修改的字符串类型。性能更低 TEXT(string) TEXT宏,作用是将字符串转换成Unicode,切记UE中使用字符串输出要使用该宏 2. FName 是UE里特有的类型。它更注重于表示名称不区分大小写,不可以更改。引擎中的资源名称都是FName类型,通

    2024年01月22日
    浏览(46)
  • 重温《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》 –– 学习笔记(一)

    第1章:走近Java 1.1 Java的技术体系 SUN 官方所定义的 Java 技术体系包括:Java程序设计语言、Java虚拟机、Class文件格式、Java API类库、第三方(商业机构和开源社区)Java类库。 其中,「Java程序设计语言」、「Java虚拟机」、「Java API类」这三个被称为 JDK(Java Deployment Kit),即

    2024年01月23日
    浏览(40)
  • 【C++】C++的类型转换

    在 C 语言中,如果 赋值运算符左右两侧类型不同 ,或者 形参与实参类型不匹配 ,或者 返回值类型与 接收返回值类型不一致 时,就需要发生 类型转化 。 C 语言中总共有两种形式的类型转换: 隐式类型 转换和显式类型转换 。 隐式类型转化:编译器在编译阶段自动进行,能

    2024年01月19日
    浏览(31)
  • 『C++』C++的类型转换

    「前言」 文章是关于C++特殊类型转换 「归属专栏」 C嘎嘎 「笔者」 枫叶先生(fy) 「座右铭」 前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 有些事不是看到了希望才去坚持, 而是因为坚持才会看到希望。 ——《十宗罪》 目录 一、C语言中的类型转换 二、为什么

    2024年02月04日
    浏览(34)
  • 【C++】C++的四种类型转换

    当等号两边的类型不同的时候、形参与实参类型不匹配的时候、返回值类型与接收返回值类型不一致时,就需要发生 类型转化 。 而类型转换又 分为隐式类型转换和显示类型转换 。 隐式类型转换是编译器在编译阶段自动进行,能转就转,不能转就编译失败。 而显示类型转换

    2023年04月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包