您的位置:首页 > 编程语言 > C语言/C++

C++ 类型转换运算符——const_cast

2017-07-21 12:02 337 查看
今天看《Effective C++》,里面提到了关于类型转换的章节,所以就来对C++的类型转换进行一定的分析和测试吧。

C++提供了四个转换运算符:

const_cast <new_type> (expression)
static_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
dynamic_cast <new_type> (expression)


它们有着相同的结构,看起来有点像是模板方法。

这些方法就是提供给开发者用来进行指针和引用的类型转换的。

用const_cast来去除对象的const限定

对于一个
const
变量,我们不能修改它的值,这是C++强制规定的,也是这个限定符的直接表现,如果我们想修改怎么办?

以下的代码显然是不行的:

const int Cint = 5;
Cint =6;             //error


我们也许可以试着用指针和引用试试?

const int Cint = 5;
//  Cint =6;             //error
int *P_Cint = (int *)&Cint;
*P_Cint = 6;


以上的代码并未真正修改到
Cint
的值,说明
C++
const
限定符执行的很完善,完全无机可乘

要不用
const_cast
试试,毕竟它主要就是负责这个的嘛:

const int Cint = 5;
const int *const PCint = &Cint;
int * castPCint = const_cast<int*>(PCint);//解除const属性
*castPCint = 6;
cout << Cint << endl;// 5
//可以看到,我们对*castPCint的修改并没有修改到Cint的值,说明C++的const的有效性
cout << "castPCint Add: " << castPCint << endl;
cout << "Cint Add: " << &castPCint << endl;
//castPCint Add: 006FF7A4
//Cint Add : 006FF78C
//可以看到,两者的地址不一样了,但是我们的确指向了同一块地址
//这种赋值行为被称为未定义行为(Undefined Behavior)”。所谓未定义,是说这个语句在标准C++中没有明确的规定,由编译器来决定如何处理。
//对于未定义行为,我们所能做的所要做的就是避免出现这样的语句。对于const数据我们更要这样保证:绝对不对const数据进行重新赋值。

//如果我们不想修改const变量的值,那我们又为什么要去const呢?
//原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数确实const的,
//但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。


以上就是
const_cast
的使用方法,是不是感觉很奇怪,转换之后的
const
内容还是完全不能进行修改,甚至连类型转换之后的指针指向的位置都被修改了,还有我发现了一个很有意思的事情,以下代码:

const int Cint = 5;
//  Cint =6;             //error
int *P_Cint = (int *)&Cint;

*P_Cint = 7;

const int *const PCint = &Cint;
int * castPCint = const_cast<int*>(PCint);//解除const属性
*castPCint = 6;
cout << Cint << endl;// 5

cout << "PC_int Add : " << P_Cint << endl;
cout << "castPCint Add : " << castPCint << endl;
cout << "Cint Add : " << &castPCint << endl;
cout << "castPCint value : " << *castPCint << endl;
cout << "PC_int value : " << *P_Cint << endl;


输出内容如下:

5  //最原始的const value的值
PC_int Add : 0097FBE8
castPCint Add : 0097FBE8
Cint Add : 0097FBC4
castPCint value : 6
PC_int value : 6


很奇怪,为什么
const_cast
和强制类型转换得到的内容地址相同呢,这就涉及到C++的未定义行为了:

所谓未定义,是说这个语句在标准C++中没有明确的规定,由编译器来决定如何处理。

位运算的左移操作也可算一种未定义行为,因为我们不确定是逻辑左移,还是算数左移。

再比如下边的语句:v[i] = i++; 也是一种未定义行为,因为我们不知道是先做自增,还是先用来找数组中的位置。

对于未定义行为,我们所能做的所要做的就是避免出现这样的语句。

对于
const
数据我们更要这样保证:绝对不对
const
数据进行重新赋值。

如果我们不想修改
const
变量的值,那我们又为什么要去
const
呢?(以下转自其他博客):

原因是,我们可能调用了一个参数不是
const
的函数,而我们要传进去的实际参数却是
const
的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用
const_cast
去除
const
限定,以便函数能够接受这个实际参数。

#include <iostream>
using namespace std;

void Printer (int* val,string seperator = "\n")
{
cout << val<< seperator;
}

int main(void)
{
const int consatant = 20;
//Printer(consatant);//Error: invalid conversion from 'int' to 'int*'
Printer(const_cast<int *>(&consatant));

return 0;
}


出现这种情况的原因,可能是我们所调用的方法是别人写的。还有一种我能想到的原因,是出现在
const
对象想调用自身的非
const
方法的时候,因为在类定义中,
const
也可以作为函数重载的一个标示符。

最后,还是要说一句:

使用
const_cast
去除
const
限定的目的绝对不是为了修改它的内容
,通过这篇,想告诉大家的就是,尽量不要使用类型转换(如果必定要使用,请使用类型转换符,方便查错)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐