Chinaunix首页 | 论坛 | 博客
  • 博客访问: 489124
  • 博文数量: 25
  • 博客积分: 111
  • 博客等级: 民兵
  • 技术积分: 1279
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-26 20:51
文章分类

全部博文(25)

文章存档

2014年(17)

2013年(8)

分类: C/C++

2013-12-15 19:57:50

下面主要对const关键字的一些性质进行说明:
1)关于变量的作用于问题
我们知道一般头文件包含类的定义,extern变量声明和和函数声明,但是const定义的变量也可以放在头文件中。这是一个例外,因为const定义的变量与不带const定义的变量存在着很大区别,例如:我们定义(假设val和cval都定义在函数外内部):

点击(此处)折叠或打开

  1. int val = 0;
  2. int const cval = 0;
虽然定义的形式相似,但是val和cval的作用域却存在很大的差别。因为val定义形式相当于extern int val =0;也就是说val是一个全局变量(在函数外部非const和static变量定义默认加上extern关键字)。如果将val的定义放在头文件中,那将导致多重定义的错误,因为每个包含此头文件的文件都相当于定义一个全局变量val。但是cval却不存在这样的问题,因为const定义的变量默认情况下是文件作用于而不是全局作用于,也就是上面中的cval的定义不会在默认情况下加上extern关键字,从而const关键字定义的变量不是一个全局变量。这样即便将cval的定义放到头文件中也不会发生多处定义的错误,最多只是包含此头文件的文件中都有一个变量cval且其值相同而已。
2)关于引用的赋值问题
    首先给出两段代码,如下:

点击(此处)折叠或打开

  1. double dval = 3.14;                   double dval = 3.14;
  2. const int& cval = dval;               int& val = dval;
虽然表达式相似,但是右边非const的val引用定义却实非法的,为了说明这个问提,我们必须从编译器是如何处理上面两个式子说起,编译器会将上面的式子展开成如下形式(不同内置类型转换时都会发生):

点击(此处)折叠或打开

  1. double dval = 3.14;
  2. int tmp = dval;
  3. const int& cval = tmp;
如果上式中右边val的定义是正确的,那么将导致与引用的定义相矛盾。我们具体举例说明,假设val的 定义是正确的,那么我们改变val的数值,根据引用的定义,我们知道dval的数值也将发生改变,但是编译器会产生一个中间值,这将导致对val的改变并不会导致dval数值相应的变化而是导致tmp数值的变化,而dval保持不变,从而这就与引用的定义相矛盾。但是const定义的变量却不存在这个问题,因为cval不允许改变cval的值,从而不会出现上面在说val时存在的问题。从而编译器允许cval的定义,但不允许val的定义。最后再说一句,上面的定义同样存在与我们平时感觉上不相符的问题,我们知道引用值应该和被引用值相同,然而对于const变量,在编译期,其值就被确定,而一旦在const之后改变了上面的dval值,这同样将导致cval和dval数值不同。为了避免这种情况,在进行上面的引用定义时,应该保持引用者和被引用者都是const定义。
3)关于函数的重载
    我们知道C++中,函数重载是通过编译器重写函数名字来实现的(c++中重写函数也会将参数考虑进去,例如类型或大小),在实现的过程中也会将const作为类型进行考虑,重写函数名字。这个很好理解,比如void f(int)和void f(const int)。一个函数类型为(void)(*)(int),而另一个函数类型为(void)(*)(const int),这样自然定义的是两个不同类型的变量。这个常常用在配对函
数中,例如重载[]操作符时。
4)关于成员函数
    有如下简单代码:

点击(此处)折叠或打开

  1. class A{
  2. public:
  3.     int get()const
  4.     {
  5.         //++val; //error
  6.         return val;
  7.     }
  8. private:
  9.     int val;
  10. };
我们知道,在成员函数get()中,是不可以改变成员变量的值的。例如在get中进行++val将会报错。为什么会报错呢?首先我们知道,在普通成员函数内访问成员变量是通过this指针来实现的,而this指针的类型为A*const。如果我们如上定义get函数时,在get函数内部的this指针的类型就不再是A* const,而是const A* const的类型。从而如果我们再去修改成员变量的值,自然会报错。也就是说,在成员函数末尾加上const相当于将A*const类型的this转化为const A* const类型的指针。
此文出处:http://blog.chinaunix.net/uid-28311809-id-4038614.html
阅读(2794) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~