C++提供了四个转换运算符:
- const_cast <new_type> (expression)
- static_cast <new_type> (expression)
- reinterpret_cast <new_type> (expression)
- dynamic_cast <new_type> (expression)
The traditional type-casting equivalents to the abover expressions would be:
(new_type) expression
new_type (expression)
一、const_cast
先来看以下一段程序const.cpp
#include <iostream> #include <stdint.h> using namespace std; int main() { const int constant = 0; // (0) int* modifier = (int*)(&constant); // (1) int* modifier2 = const_cast<int *>(&constant); //(2) *modifier = 1; *modifier2 = 2; cout<< (uint64_t*)&constant <<endl; cout<< (uint64_t*)modifier <<endl; cout<< (uint64_t*)modifier2 << endl<<endl; cout<< constant<<endl; // (3) cout<< *modifier<<endl; // (4) cout<< *modifier2<<endl; return 0; }
其中语句(1)和语句(2);都是把const int *型的指针强制变成int *型的指针。 程序运行结果如下:
0x7fff61ecef44
0x7fff61ecef44
0x7fff61ecef44
0 // 不是2 2 2
语句(3)处的输出,似乎有些异常。用以下命令,反汇编一下语句(3)和语句(4),看看有什么不同:
g++ -g3 const.cpp -o const.exe objdump -d -mi386:x86-64:intel -Slz const.exe // -d后面的参数,是为了反汇编出Intel格式的汇编
结果:
mov esi,0x0 //语句(3) mov rax,QWORD PTR [rbp-8] //语句(4) mov eax,DWORD PTR [rax]
可以看到语句(3)直接被gcc编译器当作是#define宏一样的用法给代替了。
如果把语句(0)换成:
int a = 0;
const int constant = a;
那么语句(3)的输出也会是2了。
我们不想修改const变量的值,那我们又为什么要去const呢?(参考文献1中作者总结的)
1. 我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数却是const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。(出现这种情况的原因,可能是我们所调用的方法是别人写的。)
2. 还有一种原因,const对象想调用自身的非const方法的时候。
参考:
http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html
http://www.cplusplus.com/doc/tutorial/typecasting/
http://hi.baidu.com/mckdwaymaifivze/item/392d36f0fa9605d643c36a48
http://linux.chinaunix.net/techdoc/develop/2007/12/26/975182.shtml