cpp-doc-类型转换

转换

  • 隐身转换:一般是安全的(精度小转换为精度大的)
  • 显示转换:一般是不安全的(精度大得转换为精度小的)
  • 尽可能避免强制类型转换(显示转换)
  • 如果无法避免,推荐使用新式类型转换。

旧式转换

  • (T)expr
  • T(expr)

新式转换

const_cast

const_cast<T>(expr)

  • 用来移除对象的常量性
  • 不能用于对象,一般用于指针或引用
  • 使用const_cast去除const限定的目的不是为了修改它的内容
  • 使用const_cast去除const限定,通常是为了函数能够接受这个实际参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void func(int& val)
{
cout<<"func"<<val<<endl;
}

int main(void)
{
const int val = 100;
// int n = const_cast<int>(val); // Error,不能用于对象

// int* p = &val; // Error,无法从const int* 转换成 int*
// 要进行转型,需要移除const
int *p = const_cast<int*>(&val);
*p = 200; // 这里创建了个临时变量,改变得是临时变量的内容,而不是p真正指向的地址对于的内容
cout<<"val="<<val<<endl; // 100,去除const限定不是为了修改内容

const int val2 = 200;
// int& refval2 = val2; // Error,不能指向非const引用
int& refval2 = const_cast<int&>(val2);
refval2 = 300; // 同指针一样,改变的是临时变量的内容
cout<<"val2="<<val2<<endl; // 200,

// func(val2); // Error,类型不对
func(const_cast<int&>(val2)); // 为了函数接受这个实参
}

static_cast

static_cast<T>(expr)

  • 编译器隐式执行的任何类型转换都可以由static_cast完成
  • 当一个较大的算术类型赋值给较小的类型时,可以用static_cast进行强制转换。
  • 可以将void*指针转换成为某一类型的指针
  • 可以将积累指针转成派生类指针
  • 无法将const转化为nonconst,这个只有const_cast才可以办得到
1
2
3
4
5
6
7
int main(void)
{
int n = static_cast<int>(3.14); // 精度大得转换为精度小的

void *p = &n;
int *p2 = static_cast<int*>(p);
}

reinterpret_cast

reinterpret_cast<T>(expr)

  • 通常为操作数的位模式提供较低层的重新解释,也就是说将数据以二进制存在的形式的重新解释
1
2
3
4
5
6
7
8
int i;
char *p = "This is a example";
i = reinterpret_cast<int>(p); // 此时结果,i和p的值完全相同的,i的值是p指向的地址的二进制形式

int *ip;
char *pc = reinterpret_cast<char*>(ip); // pc所指向的真实对象是int型,并非字符串
// 如果将pc当做字符指针进行操作,可能会造成运行时错误
// 如 int len = strlen(pc);

dynamic_cast

dynamic_cast<T>(expr)

  • 执行”安全向下”转型操作,也就是说支持运行时识别指针或所指向的对象,这是唯一一个无法用旧式语法来进行的转型操作。
  • 通常用于派生类、基类之间的转型