顶层const与底层const以及const的常量重叠问题

本文探讨了C++中的顶层const和底层const的概念,指出顶层const表示指针本身不可变,而底层const表示指针指向的对象不可变。在拷贝操作中,顶层const影响较小,但拷贝对象的const资格必须匹配或可转换。同时,文章提到了const对象的存储空间以及volatile关键字的作用。
摘要由CSDN通过智能技术生成

一、含义
1、顶层const表示指针本身是个常量,而用名词底层const表示指针所指的对象是一个常量;
2、更一般的说法,顶层const可以表示任意的对象是常量,这一点对任何数据类型都适用,如算数类型(整型和浮点型)、类,指针等。而底层const则与指针和引用等复合类型的基本类型部分有关。
int i = 0;
int *const p1 = &i; //顶层const,p1的值不能改变
const int ci = 42; //顶层const,ci的值不能改变
const int *p2 = &ci; //底层const,p2的值可以改变
const int *const p3 = p2; //靠右的const是顶层const,靠左的是底层const
const int &r = ci; //用于声明引用的const都是底层const

二、拷贝操作
1、当执行对象的拷贝操作时,顶层const几乎不受影响:

i = ci;                         //正确,拷贝ci的值,ci是一个顶层const,对此操作无影响
p2 = p3;                        //正确,p2和p3指向的对象类型相同,p3顶层const的部分不影响

2、当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的const资格,或者两个对象的数据类型必须能够转换。一般而言,非常量可以转换成常量,反之则不行。

int *p = p3;                     //错误,p3包含底层const,而p没有
p2 = p3;                         //正确,p2和p3都是底层const
p2 = &i;                         //正确,int*能转换成const int *
int &r = ci;                     //错误,普通的int&不能绑定到int常量上
const int &r2 = i;               //正确,const int&可以绑定到一个普通int

三、关于const的存储空间
参考http://www.cnblogs.com/yanqi0124/p/3795019.html中的大神写的内容。如下是我自己的测试代码。

“`
//测试
int main()
{

//第一种情况,使用c++中的const_cast进行转换
const int a = 1;    //若a是全局变量,则出错。
int *p = const_cast<int*>(&a);   
*p = 2;
cout << "value a = " << a << endl;            
cout << "value *p = " << *p << endl;       //输出1  2
cout << "address a = " << &a << endl;
cout << "address p = " << p << endl;

/*
第二种情况,禁用编译器优化,去掉常量重叠
volatile const int a = 1;  
int *p = const_cast<int*>(&a);
*p = 2;
cout << "value a = " << a << endl;
cout << "value *p = " << *p << endl;       //输出2  2
cout << "address a = " << &a << endl;
cout << "address p = " << p << endl;
*/


//第三种情况,使用强制转换,将内存位置存储的值改变了
//int i = 10;
//const int gc = i;   
//int *t = (int *)&gc;
//*t += 2;
//cout << *t << endl << gc << endl;                    //输出12 12


//第四种情况,编译时常量重叠
//const int i = 1;
//int *p = (int *)&i;
//*p = 2;
//cout << *p << endl << i << endl;     //输出2  1


//第五种情况,使用volatile去除编译器优化,禁用常量重叠
//volatile const int i = 1;
//int *p = (int *)&i;
//*p = 2;
//cout << *p << endl << i << endl;                   //输出2 2

return 0;

}

volatile关键字的两大作用:
一:告诉compiler不能做任何优化;
二:表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值