Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1800589
  • 博文数量: 306
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 3932
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-19 16:50
文章分类

全部博文(306)

文章存档

2018年(7)

2017年(18)

2016年(39)

2015年(35)

2014年(52)

2013年(39)

2012年(22)

2011年(29)

2010年(53)

2009年(12)

分类: C/C++

2012-11-27 18:04:16


一    const基础   
    
   如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况:   
    
   int    b    =    500;   
   const    int*    a    =    &b;          [1]   
   int    const    *a    =    &b;        [2]   
   int*    const    a    =    &b;        [3]   
   const    int*    const    a    =    &b;    [4]   
    
   如果你能区分出上述四种情况,那么,恭喜你,你已经迈出了可喜的一步。不知道,也没关系,我们可以参考《Effective    c++》Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。因此,[1]和[2]的情况相同,都是指针所指向的内容为常量(const放在变量声明符的位置无关),这种情况下不允许对内容进行更改操作,如不能*a    =    3    ;[3]为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的;[4]为指针本身和指向的内容均为常量。   
   另外const    的一些强大的功能在于它在函数声明中的应用。在一个函数声明中,const    可以修饰函数的返回值,或某个参数;对于成员函数,还可以修饰是整个函数。有如下几种情况,以下会逐渐的说明用法:A&    operator=(const    A&    a);   
   void    fun0(const    A*    a    );   
   void    fun1(    )    const;    //    fun1(    )    为类成员函数   
   const    A    fun2(    );   
    
   二    const的初始化   
    
   先看一下const变量初始化的情况   
   1)    非指针const常量初始化的情况:A    b;   
   const    A    a    =    b;   
    
   2)    指针(引用)const常量初始化的情况:A*    d    =    new    A();   
     const    A*    c    =    d;   
   或者:const    A*    c    =    new    A();   
   引用:   
     A    f;   
     const    A&    e    =    f;    //    这样作e只能访问声明为const的函数,而不能访问一般的成员函数;   
    
   [思考1]:    以下的这种赋值方法正确吗?   
   const    A*    c=new    A();   
   A*    e    =    c;   
   [思考2]:    以下的这种赋值方法正确吗?   
   A*    const    c    =    new    A();   
   A*    b    =    c;   
    
   三    作为参数和返回值的const修饰符   
    
   其实,不论是参数还是返回值,道理都是一样的,参数传入时候和函数返回的时候,初始化const变量   
   1    修饰参数的const,如    void    fun0(const    A*    a    );    void    fun1(const    A&    a);   
   调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const所修饰的部分进行常量化,如形参为const    A*    a,则不能对传递进来的指针的内容进行改变,保护了原指针所指向的内容;如形参为const    A&    a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。   
   [注意]:参数const通常用于参数为指针或引用的情况;   
   2    修饰返回值的const,如const    A    fun2(    );    const    A*    fun3(    );   
   这样声明了返回值后,const按照"修饰原则"进行修饰,起到相应的保护作用。const    Rational    operator*(const    Rational&    lhs,    const    Rational&    rhs)   
   {   
   return    Rational(lhs.numerator()    *    rhs.numerator(),   
   lhs.denominator()    *    rhs.denominator());   
   }   
    
   返回值用const修饰可以防止允许这样的操作发生:Rational    a,b;   
   Radional    c;   
   (a*b)    =    c;   
    
   一般用const修饰返回值为对象本身(非引用和指针)的情况多用于二目操作符重载函数并产生新对象的时候。   
   [总结]    一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。   
   原因如下:   
   如果返回值为某个对象为const(const    A    test    =    A    实例)或某个对象的引用为const(const    A&    test    =    A实例)    ,则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。   
    
   [思考3]:    这样定义赋值操作符重载函数可以吗?   
   const    A&    operator=(const    A&    a);   
    
   四    类成员函数中const的使用   
    
   一般放在函数体后,形如:void    fun()    const;   
   如果一个成员函数的不会修改数据成员,那么最好将其声明为const,因为const成员函数中不允许对数据成员进行修改,如果修改,编译器将报错,这大大提高了程序的健壮性。   
   五    使用const的一些建议   
    
   1    要大胆的使用const,这将给你带来无尽的益处,但前提是你必须搞清楚原委;   
   2    要避免最一般的赋值操作错误,如将const变量赋值,具体可见思考题;   
   3    在参数中使用const应该使用引用或指针,而不是一般的对象实例,原因同上;   
   4    const在成员函数中的三种用法(参数、返回值、函数)要很好的使用;   
   5    不要轻易的将函数的返回值类型定为const;   
   6除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;
阅读(1373) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~