C++ 四种强制类型转换
注意,这里部分参考了 C++四种强制类型转换。
1. 分类
关键字 说明
static_cast 用于良性转换,一般不会导致意外发生,风险很低。
const_cast 用于 const 与非 const、volatile 与非 volatile 之间的转换。
reinterpret_cast 高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换。
dynamic_cast 借助 RTTI,用于类型安全的向下转型(Downcasting)。
注意,记住他们的特点:
static_cast
是编译时静态转换。—— 相对安全。
dynamic_cast
是运行时动态转换(要求父类必须有虚函数的实现)。—— 相对安全。
const_cast
可以将const
和volatile
转换。—— 可以写只读区域。
reinterpret_cast
是直接将地址复制,没有借助任何规则进行数据调整。 —— 最灵活,但是也最危险。
2. 代码实现
我这里主要是对const_cast
的测试,结果是十分惊人的。按理说const string
是保存在.rodata
(只读)里面的,但是这里const_cast
之后,并没有把它移到可写空间,但是仍然可以对它进行写操作。
(无论如何,t
一定是只读区域,可以发现s和t的地址是连续的,所以s
应该也是只读区域)。
// g++ cast.cpp -o cast
#include <bits/stdc++.h>
using namespace std;
// 关键字 说明
// static_cast 用于良性转换,一般不会导致意外发生,风险很低。
// const_cast 用于 const 与非 const、volatile 与非 volatile 之间的转换。
// reinterpret_cast 高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换。
// dynamic_cast 借助 RTTI,用于类型安全的向下转型(Downcasting)。
// 语法格式为: xxx_cast<newType>(data)
// 这里有意思的一点是,按理说const string是保存在.rodata里面的,但是这里const_cast之后,并没有把它移到可写空间,但是仍然可以对它进行写操作。。。。
// (无论如何,t一定是只读区域,可以发现s和t的地址是连续的,所以s应该也是只读区域)
void test_const_cast() {
const string s = "Helo";
const string t = "Helo";
cout << "addr s = " << &s << ", addr t = " << &t << endl;
string& p = const_cast <string&> (s);
string* ps = const_cast <string*> (&s); // &s 的类型是 const string*
p[0] = 'h';
cout << "s = " << s << endl;
(*ps)[1] = 'E';
cout << "s = " << s << endl;
cout << "addr s = " << &s << ", addr t = " << &t << endl;
cout << "addr p = " << &p << ", addr ps = " << ps << endl;
}
void test_reinterpret_cast() {
int i = 0;
int *pi = &i;
char* ch = reinterpret_cast<char*>(pi);
++(*ch);
cout << "i = " << i << endl;
}
int main() {
test_const_cast();
test_reinterpret_cast();
exit(0);
}
编译 + 运行命令 (Linux下,以上代码复制到cast.cpp
中,命令行编译 + 运行命令)。
g++ cast.cpp -o cast
./cast