C++ STL——类型转换
注:原创不易,转载请务必注明原作者和出处,感谢支持!
注:内容来自某培训课程,不一定完全正确!
一 类型转换
类型转换的含义是通过改变一个变量的类型为别的类型从而改变变量的表示方式。C++提供了4种类型转换操作符来应对不同场合的类型转换。
| 语法 | 适用场景 | 
|---|---|
| static_cast | 一般的转换(比如C++内建类型之间的转换) | 
| dynamic_cast | 通常在基类和派生类之间转换时使用 | 
| const_cast | 主要针对const的转换 | 
| reinterpret_cast | 用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整型数 | 
总结:
(1)static_cast用于内置数据类型,具有继承关系的指针或者引用的转换。
(2)dynamic_cast只能转换具有继承关系的指针或者引用,并且只能由子类型转成父类型(基类型)。在具有基础关系的指针或者引用的转换上,相较于static_cast,dynamic_cast,添加了额外的安全检查,拒绝了类型不安全的转换,更加地安全。
(3)const_cast用来给基础数据类型,指针或者引用“加上”或者“去除”const
(4)reinterpret_cast用于任意两个无关类型的指针或者引用的转换
有关C++类型转换的一个详细案例如下所示。
class Building {};
class Animal {};
class Cat : public Animal {};
void Test1()
{
	// static_cast
	int a = 65;
	char c = static_cast<char>(a);
	cout << c << endl;
	// 基础数据类型的指针 - 无法转换
	// int *p = nullptr;
	// char *sp = static_cast<char *>(p);
	// 对象指针 - 无法转换
	// Building *building = nullptr;
	// Animal *ani = static_cast<Animal *>(building);
	// 转换具有基础关系的对象指针
	// 父类指针转子类指针
	Animal *ani = nullptr;
	Cat *cat = static_cast<Cat *>(ani);
	// 子类指针转父类指针
	Cat *soncat = nullptr;
	Animal *anifather = static_cast<Animal *>(soncat);
	// 父类引用转子类引用
	Animal aniobj;
	Animal &aniref = aniobj;
	Cat &catref = static_cast<Cat &>(aniref);
	// 子类引用转父类引用
	Cat catobj;
	Cat &catref2 = catobj;
	Animal & aniref2 = static_cast<Animal &>(catref2);
	// 总结:static_cast用于内置数据类型,具有继承关系的指针或者引用的转换
}
void Test2()
{
	// dynamic_cast只能转换具有继承关系的指针或者引用
	// 其在转换之前会进行对象类型的检查
	// 内建数据类型的转换 - 无法转换
	// dynamic_cast中的类型必须是指向完整类类型或者void *的指针或者引用
	// int a = 10;
	// char c = dynamic_cast<char>(a);
	// 非继承关系的指针的转换 - 无法转换,两者不具备继承关系
	// Animal *pani = nullptr;
	// Building *pbuilding = dynamic_cast<Building *>(pani);
	// 具有继承关系的指针 - 无法转换,父类指针转子类指针是类型不安全的
	// Animal *pani = nullptr;
	// Cat *pcat = dynamic_cast<Cat *>(pani);
	// 具有继承关系的指针 - 可以转换,子类指针转换为父类指针是类型安全的
	Cat *pcat = nullptr;
	Animal *pani = dynamic_cast<Animal *>(pcat);
	// 具有基础关系的引用 - 无法转换,原因同样是父类引用转换成子类引用是类型不安全的
	// Animal aniobj;
	// Animal &aniref = aniobj;
	// Cat &catref = dynamic_cast<Cat &>(aniref);
	// 具有继承关系的引用 - 可以转换,子类引用转父类引用是类型安全的
	Cat catobj;
	Cat &catref = catobj;
	Animal &aniref = dynamic_cast<Animal &>(catref);
	// 总结:dynamic_cast只能转换具有继承关系的指针或者引用
	// 并且只能由子类型转成父类型(基类型)
	// 在具有基础关系的指针或者引用的转换上,相较于static_cast,dynamic_cast
	// 添加了额外的安全检查,拒绝了类型不安全的转换,更加地安全
}
void Test3()
{
	// 基础数据类型
	int a = 10;
	const int &b = a;
	// b = 20; b为const引用,无法通过b来修改a的值
	// 通过const_cast去除const
	int &c = const_cast<int &>(b);
	// 通过引用c来修改a的值
	c = 20;
	// a值为20现在
	cout << "a = " << a << endl;
	// 指针
	// 去除const
	const int *p1 = nullptr;
	int *p2 = const_cast<int *>(p1);
	// 加上const
	int *p3 = nullptr;
	const int *p4 = const_cast<const int *>(p3);
	// 引用 - 去除const
	int k = 20;
	const int &r1 = k;
	int &r2 = const_cast<int &>(r1);
	// 引用 - 加上const
	int j = 30;
	int &r3 = j;
	const int &r4 = const_cast<const int &>(r3);
	// 总结:const_cast用来给基础数据类型,指针或者引用“加上”或者“去除”const
}
typedef void(*func1)(int, int);
typedef int(*func2)(int, char*);
void Test4()
{
	// 基础数据类型 - 无法转换
	// int a = 10;
	// char c = reinterpret_cast<char>(a);
	// 指针
	Building *pbuilding = nullptr;
	Animal *ani = reinterpret_cast<Animal *>(pbuilding);
	// 引用
	Building building;
	Building &bref = building;
	Animal &aniref = reinterpret_cast<Animal &>(bref);
	// 函数指针
	func1 f1;
	func2 f2 = reinterpret_cast<func2>(f1);
	// 总结:reinterpret_cast用于任意两个无关类型的指针或者引用的转换!
	// 应该尽量避免在代码中使用类型转换!!!
}
C++ STL——类型转换的更多相关文章
- c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
		C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ... 
- STL的string和wstring
		STL有字符串处理类——stirng和wstring,但是用的时候会觉得不是很方便,因为它不能像TCHAR一样根据定义的宏在char类型字符串和wchar_t进行转换,总不能因为程序要Unicode就 ... 
- STL学习小结
		STL就是Standard Template Library,标准模板库.这可能是一个历史上最令人兴奋的工具的最无聊的术语.从根本上说,STL是一些"容器"的集合,这些" ... 
- HDU 4287 Intelligent IME(string,map,stl,make_pair)
		题目 转载来的,有些stl和string的函数蛮好的: //numx[i]=string(sx); //把char[]类型转换成string类型 // mat.insert(make_pair(num ... 
- make_pair()   (STL)
		转载来的 Pairs C++标准程序库中凡是“必须返回两个值”的函数, 也都会利用pair对象 class pair可以将两个值视为一个单元.容器类别map和multimap就是使用pairs来管理其 ... 
- STL笔记(6)标准库:标准库中的排序算法
		STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ... 
- STL map 用法
		首先make_pair Pairs C++标准程序库中凡是"必须返回两个值"的函数, 也都会利用pair对象 class pair可以将两个值视为一个单元.容器类别map和mul ... 
- STL map详细用法和make_pair函数
		今天练习华为上机测试题,遇到了map的用法,看来博客http://blog.csdn.net/sprintfwater/article/details/8765034:感觉很详细,博主的其他内容也值得 ... 
- 关于Windows API、CRT和STL二三事
		1.本文编写目的 本文是为了帮助一些人弄清一些关于Windows API, C运行时程序库(CRT), 和标准C++库(STL)的基本概念.有很多人甚至是有经验的程序员在这些概念上是含糊不清的甚 ... 
随机推荐
- Marketing Cloud demo环境和API使用方法说明
			version 1.0 作者:Wang Jerry 更多问题请联系我 demo 系统url:https:/jerry.hybris.com/sap/bc/ui5_ui5/ui2/ushell/shel ... 
- Spring之Redis访问(Spring-data-redis)
			Spring-data-redis,是spring-data框架中,比较常用的,基于key-value键值对的数据持久层框架.Spring-data-redis,是一个基于Template模板开发的数 ... 
- ASE19团队项目alpha阶段model组 scrum5 记录
			本次会议于11月7日,19时整在微软北京西二号楼sky garden召开,持续12分钟. 与会人员:Jiyan He, Kun Yan, Lei Chai, Linfeng Qi, Xueqing W ... 
- web开发:javascript高级
			一.事件案例 二.循环绑定之变量污染 三.事件的绑定与取消 四.事件对象 一.事件案例 <!DOCTYPE html> <html> <head> <meta ... 
- 微信小程序开发(九)获取手机连接的wifi信息
			// succ.wxml <view>WIFI ssid:{{wifissid}}</view> <view>WIFI bssid:{{wifiBssid}}< ... 
- vue.js中父组件触发子组件中的方法
			知识点:vue.js中,父组件的method中,触发子组件中的方法,获得子组件中的定义的属性 (1)子组件 : child_crud.js var html_child_crud= "< ... 
- python: json模块 --JSON编码和解码
			json 源代码: Lib/json/__init__.py json.dump() import json numbers = [1, 2, 3, 4] with open('linshi.py', ... 
- webpack Uncaught ReferenceError: Swiper is not defined
			一.报错原因:Swiper的JS文件没有加载成功,或者说swiper丢失了依赖(正常操作是:加载后再初始化Swiper) 二.解决方法:在初始化 Swiper 的js文件中导入 Swiper impo ... 
- unreal 抓mobile 管线
			把renderdoc挂到生成的exe上 用命令行 “路径\xx.uproject” scenename -game -FeatureLevelES31 -windowed -resx=1920 -re ... 
- docker化canal与canal-adapter
			今日公司需求,需要将mysql更新实时同步到kafka中,后来又要将数据库中的一张表的变化实时同步到另一台mysql中,于是乎canal与canal-adapter紧急解决,其中踩了不少坑,下面为总结 ... 
