const 关键字

1 理解

“const应该理解为只读变量,而不是常量”这是之前死记下来的,当时并没有完全理解什么意思。最近在搜寻“const变量能否作为数组长度大小”问题时,发现原来要彻底理解const变量还是需要从编译链接的角度分析,即存储的位置是不同的。对于常量(如在程序中定义了数字123或者字符串“Hello World”)它有特定的段存储常量,即它的地址是固定的。而只读变量是在栈里的,只是其内容不能在代码中改变,访问它的时候需要弹栈操作,而不是通过地址直接定位。

基于上述理解,再来回答以下两个问题。

问题一:const变量能否作为数组长度大小,即如下代码能否编译通过?

Const int len = 10; 
int array[len];

答:基于上述理解,由于只读变量存储在栈中,所以上述貌似应该不能通过。但是在VS2008的环境中又是通过的。原因在于,与编译器有关,最新的C99编译器还有C++中一般是通过的。但是仍然不建议这样使用。

问题二:如果类中定义的常量,能否被所有类对象共享?即如果下代码中a1.constA_是否与a2.constA_相同。

class A{
         const int constA_;
}
A a1,a2;

答:是不相同的,正如上所述,const始终是变量存储在栈中,而a1的栈空间和a2的栈地址是不同的。所以不能被共享。正确的做法是使用枚举常量,见参考文献1。

 2 const引用

非const引用不能指向 const对象,但const引用能够指向非const对象。

const int a=1024
int b=20;
const int& a1 = a;  //正确
const int& b1 = b;  //正确
int& a2 = a;       //错误

另外,附一种奇葩的用法,在低精度引用变量来自高精度时,可以通过const引用实现。但是修改引用是不能修改原变量的值的。

double d = 3.15;    //正确
int& a1 = d;        //错误
const int& a2=&d;    //通过,但是a的值是不会随d的变化而改变的。因为这一语句会被编译器转换成两条语句“临时int型变量等于d”“a2指向临时变量”

类似地,当const对象不允许直接使用const_cast去除const属性,但指针或者引用是允许的,同上转换之后,两个是没有任何关联的,修改非const对象是不会影响到const对象的。如下代码所示。

         const int b = 100;
         //intd = const_cast<int>(b) ;  //不允许
         int d = *(const_cast<int*>(&b));  //允许

综上,const_cast用来移除常量且用于指针或者引用,且目的并不是修改(因为转过换后两者没有关系)而是让函数接受。

关于使用const_cast转换后,到底与被转换的关系,这取决于是转换后,是否取值,如果取值了,则是把申请个临时变量,如果只是单纯的指针,那么指向的是同一个地址。如下所述。

方式一:

cosnt int a = 100;

int b = *const_cast<int*>(&a);   

cout << &b << " "<< &a << endl;   //此时a和b的地址是两个不同的。

方式二:

const int a = 100;

int *b =const_cast<int*>(&a);

cout <<b<<" "<<&a << endl; //此时a和b是同一个地址

3 初始化

Const变量如果只是作为普通函数中声明的,那么必须在声明时就初始化。如果是作为类的成员变量,那么初始化必须在初始化列表中。

只能在初始化列表中初始化的变量。

(1)const成员(2)引用成员(3)如果成员是类对象,且该类没有默认的构造函数(4)基类,且基类没有默认构造函数

4 const 修饰成员函数

    当const修改成员函数时,首先需要在函数参数列表后面添加 const,然后在定义时,也需要加上const修饰。同时,用const 修饰的成员函数不能修改类的成员变量。

class Test
{
public :
     void TestConstFunction(void) const;
}
void Test::TestConstFunction(void) const
{
    //iValue_= 100; 错误不允许修改
}


        
参考文献

[1] http://blog.sina.com.cn/s/blog_5fa144950100ko07.html

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值