注:原创不易,转载请务必注明原作者和出处,感谢支持!

注:内容来自某培训课程,不一定完全正确!

一 类型转换

类型转换的含义是通过改变一个变量的类型为别的类型从而改变变量的表示方式。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——类型转换的更多相关文章

  1. c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast

    C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...

  2. STL的string和wstring

    STL有字符串处理类——stirng和wstring,但是用的时候会觉得不是很方便,因为它不能像TCHAR一样根据定义的宏在char类型字符串和wchar_t进行转换,总不能因为程序要Unicode就 ...

  3. STL学习小结

    STL就是Standard Template Library,标准模板库.这可能是一个历史上最令人兴奋的工具的最无聊的术语.从根本上说,STL是一些"容器"的集合,这些" ...

  4. HDU 4287 Intelligent IME(string,map,stl,make_pair)

    题目 转载来的,有些stl和string的函数蛮好的: //numx[i]=string(sx); //把char[]类型转换成string类型 // mat.insert(make_pair(num ...

  5. make_pair() (STL)

    转载来的 Pairs C++标准程序库中凡是“必须返回两个值”的函数, 也都会利用pair对象 class pair可以将两个值视为一个单元.容器类别map和multimap就是使用pairs来管理其 ...

  6. STL笔记(6)标准库:标准库中的排序算法

    STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...

  7. STL map 用法

    首先make_pair Pairs C++标准程序库中凡是"必须返回两个值"的函数, 也都会利用pair对象  class pair可以将两个值视为一个单元.容器类别map和mul ...

  8. STL map详细用法和make_pair函数

    今天练习华为上机测试题,遇到了map的用法,看来博客http://blog.csdn.net/sprintfwater/article/details/8765034:感觉很详细,博主的其他内容也值得 ...

  9. 关于Windows API、CRT和STL二三事

    1.本文编写目的    本文是为了帮助一些人弄清一些关于Windows API, C运行时程序库(CRT), 和标准C++库(STL)的基本概念.有很多人甚至是有经验的程序员在这些概念上是含糊不清的甚 ...

随机推荐

  1. 使用postman创建Marketing Cloud的Contact

    首先在Marketing Cloud的UI上创建一个contact: 观察Chrome开发者工具network标签页里的HTTP请求: https://jerry.gcdemo.hybris.com/ ...

  2. 程序面试题——C实现

    平台:win10 x64 +VC6.0 2019/5/22 1.合并三个有序的链表 链表节点定义struct node{    int val;    struct node* next;}; str ...

  3. Error:Execution failed for task ':app:compileDebugJavaWithJavac'

    百度一下呗 查找了各种解决方案,都不对症. 最后发现,造成这种异常的原因有很多.具体的还是要去终端编译,查看到底是什么地方出错了,然后具体问题具体分析. 终端进入项目的根目录,然后输入命令 ./gra ...

  4. django的几种缓存配置

    前言 首先说,为什么要用缓存的,由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存 ...

  5. 二十:强类型HTML辅助方法

    1. 强类型HTML辅助方法的使用 1. HTML辅助方法 例如,要输出一个文本框 @Html.TextBox("email") 2.强类型HTML辅助方法 命名规则是: HTML ...

  6. 跟着我一步一步的搭建一个基于springcloud的微服务实例

    Table of Contents generated with DocToc microservicecloud 插件推荐 建立父工程Microservicecloud 搭建Employ员工服务 创 ...

  7. Python怎么检验数据的正态分布

    在对数据建模前,很多时候我们需要对数据做正态性检验,进而通过检验结果确定下一步的分析方案.下面介绍 Python 中常用的几种正态性检验方法: scipy.stats.kstest kstest 是一 ...

  8. Spark任务调度初识

    前置知识 spark任务模型 job:action的调用,触发了DAG的提交和整个job的执行. stage:stage是由是否shuffle来划分,如果发生shuffle,则分为2个stage. t ...

  9. eclipse调试断点

    1.条件断点 如果你不知道如何添加断点,只需点击左边面板(行号前面)断点即被创建.在调试界面中,“断点”视图会把所有被创建的断点列出来.我们可以给它加一个布尔条件,也就是说,该断点会被激活并且如果布尔 ...

  10. BZOJ 3658: Jabberwocky (双向链表+BIT)

    题意 平面上有n个点,每个点有k种颜色中的一个.你可以选择一条水平的线段获得在其上方或其下方的所有点,请求出你最多能够得到多少点,使得获得的点并不包含所有的颜色. 分析 线段可以向上向下,那么我们只考 ...