Effective C++ 条款03

尽可能使用const

1.const和指针

如果const关键字在星号左边,表示被指物是常量; const T* t 
如果出现在星号右边,表示指针自身是常量; T* const t 
如果出现在星号两边,表示被指物和指针两者都是常量;const T* const t

总结:const靠近*号,那么申明的指针就是常量。远离*的const就是描述指针的所指量为常量

2.const和迭代器

STL中的迭代器实际上本质是以指针实现的,所以可以把一个迭代器看作是一个指针,可以用指针的性质去套迭代器的性质。

std::vector <int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
const std::vector <int>:: iterator it = vec.begin();
std::vector <int> ::const_iterator iit =vec.begin();
    *it =10;
//    ++it;  错误
//    *iit = 30; 错误
    iit++;

这里的it就是常量,*it是可以被改变的;*iit是常量,iit可以被改变。

总结:const_iterator 相当于const T* (指向的内存不能被改变)

           const ……iterator 相当于T* const 

3.另函数返回一个常量,可以降低因用户错误造成的意外

例如重载*操作符时的声明如下:

const Complex operator* (const Complex& lhs, const Complex& rhs);
返回const对象可以避免像 (a*b)= c 这样的情况发生,通常表现为这样的错误:

if (a*b = c)//实际是想判断是否相等,即应为==而不是=
此时因为a*b返回的对象是const对象,不可修改,因此会报错,使得程序员发现这个错误并修改。
 

4.通过mutable去除non-static成员变量的bitwise constness约束:

bitwise const认为,成员函数只有在不更改对象的任何成员变量时才可以说是const,也就是它不更改对象内的任何一个bit。 
bitwise const正是c++对常量性的定义,因此const成员函数不能更改对象内任何non-static成员变量。 

class Text {
public:
    std::size_t length() const;
private:
    char* pText;
    std::size_t textLength;
    bool lengthValid;
};

std::size_t Text::length() const {
    if (!lengthValid) {  //错误,在const函数内要改变textLength和lengthValid的值
        textLength = std::strlen(pText);
        lengthValid = true;
    }
    return textLength;
}

这样的code是不能通过bitwsie const的编译器,编译器提示:

cannot assign non-static data member within const funciton ……

如果要使textLength、lengthValid可以修改,需要用mutable释放掉non-static成员变量的bitwise const约束:

...
private:
    mutable std::size_t textLength;  ///mutable的意思就是成员变量可能总是被更改,即使在const成员函数内
    mutable bool lengthValid;
...

加上mutable ,编译器报警消失

5. 在const和non-const成员函数中避免重复

一句话就是:利用const函数实现内容,去实现non-const函数,就是需要进行数据类型的转换

const char& operator[] (std::size_t position) const {
    ...   ////函数实现
    return text[position];
}

char& operator[] (std::size_t position) {
    return const_cast<char&>(static_cast<const Text&>(*this)[posistion]);
}

这里的下面一个操作符,里面有两次转型,第一次用来为*this从其原始类型TextBlock& 转型为const TextBlock&,通过添加const

第二次是从const operator[ ] 的返回值中移除const。

参考:https://blog.csdn.net/unirrrrr/article/details/80890252

猜你喜欢

转载自blog.csdn.net/qq_31638535/article/details/88663851