二、常类型转换
请思考,这段代码可以编译通过吗?会不会正常打印出200?
答案是否定的。因为变量i用const修饰后,它的指针就不再是int*,也是const int* ,而C++中处于安全性的考虑是不允许将常量指针const int*强制转换成int*的。上面的代码根本就不会通过编译器的编译。
常类型转换const_cast<>的提出就是为了解决这个问题,我们将上述代码改为:
const_cast<>可以将带有常属性的指针或者引用(注意只能是指针或者引用哦,不能是常属性变量)强制转换成不带常属性的指针或者引用。当改成上述代码之后,你就会发现编译通过了!执行程序,会不会是我们想要的结果200呢?
答案也是否定的?
为什么?是const_cast<>没起作用吗?
这得要提到编译器的一个优化策略,我们知道程序执行时,变量是存在栈里的,没需要操作一个变量程序都要读一次栈。编译器为了提高程序效率,在编译期间就将常量变量用其值进行了替换,也就是说在本程序中,编译完成后cout<<i<<endl中的i就被替换成了100,所以运行时你再修改也是没有用的,程序打印出的还是100。
怎么解决这个问题呢?我们这样声明i:
const volatile int i=100;
加上volatile关键字后,告诉编译器i这个变量具有挥发性,随时可能会变化的,不要进行常量优化,就得到了我们想要的结果。
修改后的代码:
运行结果:
常类型转换,是去除变量的常量属性,我们先看下面的例子:
#include<iostream>
using namespace std;
int main()
{
const int i=100;
int* pi=&i;
*pi=200;
cout<<i<<endl;
return 0;
}
请思考,这段代码可以编译通过吗?会不会正常打印出200?
答案是否定的。因为变量i用const修饰后,它的指针就不再是int*,也是const int* ,而C++中处于安全性的考虑是不允许将常量指针const int*强制转换成int*的。上面的代码根本就不会通过编译器的编译。
[Hyman@Hyman-PC cplus]$ g++ cast.cpp
cast.cpp: In function ‘int main()’:
cast.cpp:7: 错误:从类型‘const int*’到类型‘int*’的转换无效
常类型转换const_cast<>的提出就是为了解决这个问题,我们将上述代码改为:
#include<iostream>
using namespace std;
int main()
{
const int i=100;
int* pi=const_cast<int*>(&i);
*pi=200;
cout<<i<<endl;
return 0;
}
const_cast<>可以将带有常属性的指针或者引用(注意只能是指针或者引用哦,不能是常属性变量)强制转换成不带常属性的指针或者引用。当改成上述代码之后,你就会发现编译通过了!执行程序,会不会是我们想要的结果200呢?
答案也是否定的?
为什么?是const_cast<>没起作用吗?
这得要提到编译器的一个优化策略,我们知道程序执行时,变量是存在栈里的,没需要操作一个变量程序都要读一次栈。编译器为了提高程序效率,在编译期间就将常量变量用其值进行了替换,也就是说在本程序中,编译完成后cout<<i<<endl中的i就被替换成了100,所以运行时你再修改也是没有用的,程序打印出的还是100。
怎么解决这个问题呢?我们这样声明i:
const volatile int i=100;
加上volatile关键字后,告诉编译器i这个变量具有挥发性,随时可能会变化的,不要进行常量优化,就得到了我们想要的结果。
修改后的代码:
#include<iostream>
using namespace std;
int main()
{
const volatile int i=100;
int* pi=const_cast<int*>(&i);
*pi=200;
cout<<i<<endl;
return 0;
}
运行结果:
[Hyman@Hyman-PC cplus]$ ./a.out
200