前言
C++提供了四种类型转换操作符,
- const_cast
- static_cast
- dynamic_cast
- reinterpret_cast
对于const_cast,大部分书籍是这样描述它的:
- const_cast将转换表达式的const或者volatile性质。
- 四种类型转换操作符中,剩余三种无法转换const性质,强制转换会导致编译错误。
- const_cast只能转换const或者volatile特性,转换其他性质将会导致编译错误。
疑惑
先来看一段代码:
const int a = 22;
int *b = &a;
在c中这段代码可以编译,顶多出现一个warning,之后便可以对b进行操作了,也就是说改变了a和b的值,const就失去了意义。但是在c++中是不允许的,编译无法通过,const的值是无法改变的。 对于前面描述的第一点,我还以为它能改变const的值,但是我试了下:
#include<iostream>
int main()
{
const int constant = 22;
std::cout<<"constant = "<<constant<<std::endl;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
std::cout<<"constant = "<<constant<<" add of constant: "<<&constant<<std::endl;
std::cout<< "*const_p = " <<*const_p<<" add of *const_p: " <<const_p<<std::endl;
std::cout<<"*modifier = "<< *modifier<<" add of modifier: "<<modifier<<std::endl;
*modifier = 7;
std::cout<<"constant = "<<constant<<" add of constant: "<<&constant<<std::endl;
std::cout<< "*const_p = " <<*const_p<<" add of *const_p: " <<const_p<<std::endl;
std::cout<<" *modifier = "<< *modifier<<" add of modifier: "<<modifier<<std::endl;
return 0;
}
编译输出结果之后:
constant = 22 add of constant: 0x7ffc25e769bc
*const_p = 22 add of *const_p: 0x7ffc25e769bc
*modifier = 22 add of modifier: 0x7ffc25e769bc
constant = 22 add of constant: 0x7ffc25e769bc
*const_p = 7 add of *const_p: 0x7ffc25e769bc
*modifier = 7 add of modifier: 0x7ffc25e769bc
看结果可以知道,constat变量并未改变,只是const_p指针指向的内容改变了,看来C++还是很严谨的,常量值无法改变。
作用
那么问题来了,const_cast既然不能改变const值,有什么作用呢? 我们调用一个参数不是const类型的函数,但是传进去的参数是const,这时候const_cast作用就显现出来了:
#include<iostream>
void getMaxValue(int * num) ;
int main()
{
const int constant = 22;
const int* const_p = &constant;
getMaxValue(const_p);
return 0;
}
void getMaxValue(int *num) {return;}
编译时报错:
test12.cpp:9:24: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
getMaxValue(const_p);
如果改成:
getMaxValue(cosnt_cast<int*>(const_p));
那么编译通过,顺利执行。 在这种情况下,我们初心并不是为了改变变量值,只是出于无奈,不得不转换类型去调用函数。 除此之外,还有一种很少见的情况,见代码:
int constant = 22;
const int* const_p = &constant;
const指针指向了变量,我们后续需要改变constant的值,但是手头上只有指针了,只能通过const_cast来实现了。
int constant = 22;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = 23;
这种情况其实是没事找事,有点钻牛角尖的意思,直接constant = 23不就好了嘛。
|