C++ 类型转换运算符——const_cast
2017-07-21 12:02
387 查看
今天看《Effective C++》,里面提到了关于类型转换的章节,所以就来对C++的类型转换进行一定的分析和测试吧。
C++提供了四个转换运算符:
它们有着相同的结构,看起来有点像是模板方法。
这些方法就是提供给开发者用来进行指针和引用的类型转换的。
以下的代码显然是不行的:
我们也许可以试着用指针和引用试试?
以上的代码并未真正修改到
要不用
以上就是
输出内容如下:
很奇怪,为什么
所谓未定义,是说这个语句在标准C++中没有明确的规定,由编译器来决定如何处理。
位运算的左移操作也可算一种未定义行为,因为我们不确定是逻辑左移,还是算数左移。
再比如下边的语句:v[i] = i++; 也是一种未定义行为,因为我们不知道是先做自增,还是先用来找数组中的位置。
对于未定义行为,我们所能做的所要做的就是避免出现这样的语句。
对于
如果我们不想修改
原因是,我们可能调用了一个参数不是
出现这种情况的原因,可能是我们所调用的方法是别人写的。还有一种我能想到的原因,是出现在
最后,还是要说一句:
使用
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
限定的目的绝对不是为了修改它的内容,通过这篇,想告诉大家的就是,尽量不要使用类型转换(如果必定要使用,请使用类型转换符,方便查错)
相关文章推荐
- C++类型转换运算符: static_cast<>,reinterpret_cast<>,dynamic_cast<>, const_cast<>
- C++类型转换运算符 static_cast,dynamic_cast,reinterpret_cast,const_cast
- C++类型转换运算符 static_cast,dynamic_cast,reinterpret_cast,const_cast
- 【C++基础】类型转换运算符的使用方法(reinterpret_cast、 const_cast、static_cast、dynamic_cast)
- C++类型转换运算符之const_cast<newtype>(expression)
- C++的类型转换运算符(二)——reinterpret_cast 与 const_cast
- C++ 学习笔记(4)表达式、运算符、类型转换(static_cast、const_cast、reinterpret_cast、dynamic_cast)
- C++的类型转换运算符(二)——reinterpret_cast 与 const_cast
- 关于c++ 强制转换类型运算符 static_cast、dynamic_cast、reinterpret_和const_cast
- 标准c++中四种强制转换类型运算符介绍 const_cast,reinterpret_cast,static_cast,dynamic_cast
- C++语言基础(24)-四种类型转换运算符(static_cast、dynamic_cast、const_cast和reinterpret_cast)
- 关于c++ 强制转换类型运算符 static_cast、dynamic_cast、reinterpret_和const_cast
- C++中四种类型转换运算符的使用方法(reinterpret_cast,const_cast,static_cast,dynamic_cast)
- C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
- C++标准转换运算符const_cast
- C++ 四种类型强制转换 static_cast、const_cast、reinterpret_cast、dynamic_cast
- C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast
- 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
- C++标准转换运算符const_cast
- C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast