文章目录
1. 类型转换运算符种类
关键概念:存在继承关系之间的转换规则
- 从派生类向基类的类型转换只对指针或引用类型有效。
- 基类向派生类不存在隐式类型转换。
- 和任何其他成员一样,派生类向基类的类型转换也可能会由于访问受限而变得不可行。
参考书籍:C++ Primer (第5版)—— 15.2.3 类型转换与继承
| 类型转换运算符 | 作用| 语法|
|–|–|–|
| dynamic_cast | 将派生类指针转换为基类指针,主要是为了确保可以安全的调用虚函数 | dynamic_cast(expression)|
| const_cast | 有时需要这样一个值,它在大多数时候是常量,有时又想要修改,这时可以将这个值声音为const,在需要修改的时候使用const_cast |const_cast(expression) |
| static_cast | 当type_name可被隐式转换为expression所属的类型或expression可被隐式转换为type_name所属的类型时,转换才合法,否则将出错 | static_cast(expression)
| reinterpret_cast | 类似C语言中的指针指针类型转换,例如 int n = 20; char p = (char)&n;这里的(char*)即是C语言的强制类型转换语法 |reinterpret_cast(expression)
注意:与通用转换机制相比,这四种转换提供了更安全,更明确的类型转换
2. 代码示例
2.1 dynamic_cast
#include <iostream>
using namespace std;
class CPerson
{
public:
virtual void Show()
{
cout << "CPerson" << endl;
}
};
class CStudent : public CPerson
{
public:
virtual void Show()
{
cout << "CStudent" << endl;
}
};
int main()
{
//! 将CStudent对象地址赋值给CPerson*:成功,返回CPerson*;失败,返回0(即空指针)
CPerson *pPer = nullptr;
if (pPer = dynamic_cast<CPerson *>(new CStudent)) //< 转换成功再调用虚函数
{
pPer->Show();
}
return 0;
}
2.2 const_cast
int n = 10;
const int *p = &n;
// *p = 29; 错误,无法指针指向的值
int *p2 = const_cast<int*>(p);
*p2 = 29; //< 正确,可以删除const
2.3 static_cast
class CPerson{};
class CStudent: public CPerson{}; //< 继承CPerson
class CPond{}; //< 和Cperson,CStudent无关
int main()
{
CPerson per;
CStudent stu;
CPerson *pPer = static_cast<CPerson*>(&stu); //< 合法
CStudent* pStu = static_cast<CStudent*>(&per); //< 合法
// CPond *pPon = static_cast<CPond*>(&stu); //< 非法,CPond与CStudent不相关
return 0;
}
2.4 reinterpret_cast
- 通常,这样的转换适用于依赖于实现的底层编程技术,是不可移植的。例如,不同系统在存储多字节整形时,可能以不同的顺序存储其中的字节。
- 并不支持所有的类型转换,例如,可以将指针类型转换为足以存储指针表示的整形,但不能将指针转换为更小的整数或者浮点型;另一个限制是,不能将函数指针转换为数据指针,反之亦然。
StuPer stuP = {10, 20};
cout << *(short*)((char*)(&stuP)+2) << endl; //< C语言的指针类型转换语法取short b值,输出为20
cout << *(reinterpret_cast<short*>( (reinterpret_cast<char*>(&stuP)+2))); //< c++ 指针类型转换语法,输出为20
3. 参考书籍
C++ Primer Plus(第6版)——15.5 类型转换运算符
4. 尽量少做转型动作
effective c++ 条款27 尽量少做转型动作
类型转换运算符 | 作用 | 语法 |
---|---|---|
dynamic_cast | 主要用来执行“安全向下转换”,也就是用来决定某对象是否归属继承体系中的某个类型,它是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作 | |
const_cast | 通常被用来将对象的常量性转出(cast away the constness),它也是唯一有此能力的c+±sytle转型操作符 | |
static_cast | 用来强迫隐式转换(implicit conversion),例如将non-const对象转为const对象(就像条款3所为),或将int转为double等等。它也可以用来执行上述多种转换的反向转换,例如将void*指针转为typed指针,将pointer-to-base转为pointer-to-derived。但它无法将const转为non-const——这个只有const_cast才办得到 | |
reinterpret_cast | y意图执行低级转型,实际动作(及结果)可能取决于编译器,这也就表示它不可移植。例如将一个pointer to int转型为一个int。这一类转型在低级代码意外很少见。本书只使用一次,那是在讨论如何针对原始内存(raw memory)写出一个调试用的分配器(debugging allocator)时,见条款50 |
- c++ primer 第五版——4.11.3 显示转换如下图