const的思考[2]

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 hustli 的 blog

        int const *a;       file://const修饰指向的对象,a可变,a指向的对象不可变
        int *const a;       file://const修饰指针a,     a不可变,a指向的对象可变
        const int *const a;  file://指针a和a指向的对象都不可变
   (5)修饰常引用
        使用const修饰符也可以说明引用,被说明的引用为常引用,该引用所引用的对象不能被更新。其定义格式如下:
       const double & v;
  (6)修饰函数的常参数
        const修饰符也可以修饰函数的传递参数,格式如下:
        void fun(const int var);
        告诉编译器var在函数体中的无法改变,从而防止了使用者的一些无意的或错误的修改。    
   (7)修饰函数的返回值:
        const修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下:
            const int fun1();
            const myclass fun2();
   (8)修饰类的成员函数:
        const修饰符也可以修饰类的成员函数,格式如下:
            class classname
     {
             public:
                  int fun() const;
                    .....
             };
        这样,在调用函数fun时就不能修改类里面的数据
    (9)在另一连接文件中引用const常量
         extern const int i;     file://正确的引用
         extern const int j=10;  file://错误!常量不可以被再次赋值
    另外,还要注意,常量必须初始化!
         例如:
             const int i=5; 

4、几点值得讨论的地方:
   (1)const究竟意味着什么?
        说了这么多,你认为const意味着什么?一种修饰符?接口抽象?一种新类型?
        也许都是,在stroustup最初引入这个关键字时,只是为对象放入rom做出了一种可能,对于const对象,c++既允许对其进行静态初始化,也允许对他进行动态初始化。理想的const对象应该在其构造函数完成之前都是可写的,在析够函数执行开始后也都是可写的,换句话说,const对象具有从构造函数完成到析够函数执行之前的不变性,如果违反了这条规则,结果都是未定义的!虽然我们把const放入rom中,但这并不能够保证const的任何形式的堕落,我们后面会给出具体的办法。无论const对象被放入rom中,还是通过存储保护机制加以保护,都只能保证,对于用户而言这个对象没有改变。换句话说,废料收集器(我们以后会详细讨论,这就一笔带过)或数据库系统对一个const的修改怎没有任何问题。
   (2)位元const v.s. 抽象const?
        对于关键字const的解释有好几种方式,最常见的就是位元const 和 抽象const。下面我们看一个例子:
        class a
        {
         public:
               ......
               a f(const a& a);
               ......
         };
         如果采用抽象const进行解释,那就是f函数不会去改变所引用对象的抽象值,如果采用位元const进行解释,那就成了f函数不会去改变所引用对象的任何位元。
         我们可以看到位元解释正是c++对const问题的定义,const成员函数不被允许修改它所在对象的任何一个数据成员。
         为什么这样呢?因为使用位元const有2个好处:
         最大的好处是可以很容易地检测到违反位元const规定的事件:编译器只用去寻找有没有对数据成员的赋值就可以了。另外,如果我们采用了位元const,那么,对于一些比较简单的const对象,我们就可以把它安全的放入rom中,对于一些程序而言,这无疑是一个很重要的优化方式。(关于优化处理,我们到时候专门进行讨论)
         当然,位元const也有缺点,要不然,抽象const也就没有产生的必要了。
         首先,位元const的抽象性比抽象const的级别更低!实际上,大家都知道,一个库接口的抽象性级别越低,使用这个库就越困难。
         其次,使用位元const的库接口会暴露库的一些实现细节,而这往往会带来一些负面效应。所以,在库接口和程序实现细节上,我们都应该采用抽象const。
         有时,我们可能希望对const做出一些其它的解释,那么,就要注意了,目前,大多数对const的解释都是类型不安全的,这里我们就不举例子了,你可以自己考虑一下,总之,我们尽量避免对const的重新解释。
   (3)放在类内部的常量有什么限制?
        看看下面这个例子:
        class a
        {
         private:

本文关键:const
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top