C++ 中 const_cast 作用详解

const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。

我们需要注意的是:变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。

用法:const_cast<type>(expression)

通过const_cast运算符,也只能将const type*转换为type*,将const type&转换为type&。

也就是说源类型和目标类型除了const属性不同,其他地方完全相同。

我们先来看这样一段代码:

#include <iostream>
using namespace std;
 
int main () {
	const int data = 100;
    int *pp = (int *)&data;
    *pp = 300;
    cout << "data = " << data << "\t地址 : " << &data << endl << endl ;
	cout << "  pp  = " << *pp << "\t地址 : " << pp << endl << endl ;
	int *p = const_cast<int*>( &data ) ;
	cout << "data = " << data << "\t地址 : " << &data << endl << endl ;
	cout << "  p  = " << *p << "\t地址 : " << p << endl << endl ;
	*p = 200 ;
 
	cout << "data = " << data << "\t地址 : " << &data << endl << endl ;
	cout << "  p  = " << *p << "\t地址 : " << p << endl << endl ;
 
	return 0 ;
}

运行结果如下:

 

 

很奇怪? data 的地址是 0x6ffdfc, p 指向的地址也是 0x6ffdfc, 但是修改 p 之后, 同一个地址上的内容却不相同。

可能是 const 的问题? const 的机制,就是在编译期间,用一个常量代替了 data。这种方式叫做常量折叠。

常量折叠与编译器的工作原理有关,是编译器的一种编译优化。在编译器进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。所以在上面的例子中,编译器在优化的过程中,会把碰到的data(为const常量)全部以内容100替换掉,跟宏的替换有点类似。

常量折叠只对原生类型起作用,对我们自定义的类型,是不会起作用的。

我们看下面的代码:

#include <iostream>
#include <stdio.h>
 
using namespace std;
 
typedef struct _Test {
    int a;
    _Test() {
        a = 10;
    };
    void func {}
} Test;
 
int main()
{
    const Test b;
    Test *b1 = const_cast<Test *>(&b);
    cout << "b = " << b.a << endl;
    b1->a = 100;
    cout << "b = " << b.a << ", *b1 = " << b1->a << endl;
 
    return 0;
    }

const_cast去除函数返回值的const属性。

函数的形参为非const,当我们传递一个const修饰的变量时可以通过const_cast去除该变量的const属性。

#include <iostream>
using namespace std;
 
const int *f(int *t)
{
	int *p = new int;
	*p = 100;
	return p;
}
 
int main () {
	int x = 1;
	int *p1 = const_cast<int *>(f(&x));
	*p1 = 1000;
	
	const int *y = new int(10);
	//int *p2 = const_cast<int *>(f(y));//[Note] in passing argument 1 of 'const int* f(int&)'
	int *p2 = const_cast<int *>(f(const_cast<int *>(y)));
	cout << *y <<endl;
//	*y = 100; //[Error] assignment of read-only location '* y'
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值