《Effective C艹》读书笔记(2)

条款03:尽可能使用const

    面对指针的时候,既可以指出指针自身,也指针所指向的事物,或者两者都是 const。

    char str[] = "hello";
    char* p = str;                   //指针不是const,字符串也不是const
    const char* p = str;             //指针不是const,字符串是const
    char* const p = str;             //指针是const,字符串不是const
    const char* const p = str;       //指针是const,字符串也是const

     为了方便记忆。如果关键字const出现在星号左边,表示被指物是const。如果const出现在星号右边,表示指针自身是const。如果出现在星号两边,则两者都是const。

    

    声明迭代器const就像声明指针为const一样,表示这个迭代器不得指向不同的东西,但是他所指向的东西是可以改动的。如果你希望迭代器所指向的东西不可以被改动,你需要的是const_iterator.

   vector<int>vec;
    const vector<int>::iterator iter = vec.begin();  //这里迭代器类似于 T* const 指针的指向不能改变
    *iter = 10;                                      //没问题,改变iter所指物
    ++iter;                                          //error 不可以改变指向
    vector<int>::const_iterator cIter = vec.begin()  //类似于T* const 所指的对象不可改变

    另函数返回一个常量值,往往可以降低因为客户错误而造成意外,而又不至于放弃安全性和高效性。

    考虑下面一种情况

class myInt{
public:
    int num;
    myInt(int a){num = a;}
};
const myInt operator*(const myInt& li,const myInt& ri){
    const myInt aa(li.num*ri.num);
    return aa;
}

     至于为什么要把返回值设为const。原因是如果不这样,客户就会写出如下代码:

myInt a,b,c;
(a*b) = c;

     如果操作符*的返回值是const的,这样的代码就是直截了当的不合法的。将operator* 返回值设为const就是为了避免那个没有意义的赋值动作。

    const 成员函数

    将const实施与成员函数的目的,是为了确认该函数可作用于const对象。当两个成员函数只是const属性不同的时候,他们是可以重载的。

class myInt{
public:
    int num;
    myInt(int a){
        num = a;
    }
    int& getValue(){
        int res = num*num;
        return res;
    }

    const int& getValue() const{
        const int res = num;
        return res;
    }
};

 我们可以这样使用上述函数

    myInt mi(10);                          
    cout<<mi.getValue()<<endl;        //使用non-const函数,输出100
    const myInt ma(20);
    cout<<ma.getValue()<<endl;        //使用const函数,输出20

要注意这里的返回值是一个指向int的引用。这是因为,如果返回的是一个int的话,下面的语句将无法通过编译

mi.getValue()+=1;

 那是因为,如果返回的是内置类型,那么改动函数返回值从来都不合法,即便这样是合法的,你改变的也是mi.value的一个副本,而不是这个变量本身。

    

猜你喜欢

转载自bbezxcy.iteye.com/blog/2240484
今日推荐