Effective C++条款 —— 尽可能使用 const

  • const允许你指定一个语义约束(即指定一个“不该被改动”的对象),而编译器会强制实施这项约束。

  • const与指针
    如果关键字const出现在星号左边,则表示被指物是常量;
    如果出现在星号右边,则表示指针自身是常量。

    int i = 0;
    const int *p;			// 指向常量
    int * const p = &i;		// 指针本身是常量
    
  • 令函数返回一个常量值,可以预防“无意义的赋值动作”。

    const Rational operator*(const Rational &lhs, const Rational &rhs);
    
    Rational a, b, c;
    (a*b) = c;		// 可以预防此类错误
    

  • const成员函数

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

      一个更改了“指针所指物”的成员函数虽然不能算是const,但如果只有指针隶属于对象,而指针所指物不属于对象的成员,那么此函数为bitwise const,不会引发编译器异议!

    • logical constness 阵营:一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此

      mutable关键字:它可以释放掉non-static成员变量的bitwise constness约束,即它使它修饰的成员变量即使在const成员函数内也可以被修改。

      class CTextBlock {
      private:
          char *pText;
          mutable std::size_t textLength;			// 总是可被修改
          mutable bool lengthIsValid;					// 总是可被修改
          ...
      };
      

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

      class TextBlock {
      public:
          const char& operator[](std::size_t position) const {
              ...
              return text[position];
          }
          
          // 在非 const 成员函数中使用 const 成员函数
          char& operator[](std::size_t position) {
              return
                  const_cast<char&>(
                  	static_cast<const TextBlock&>(*this)[position]
              	);
          }
      };
      

      第一次转型:为 *this 添加const,这使接下来调用operator[]时得以调用const版本,而不至于递归调用自身。且注意:目标类型为一个引用,直接引用 *this,而不是转型之后得到一个 *this的副本。

      // 上述代码可拆分为如下代码
      const TextBlock &ref = static_cast<const TextBlock&>(*this);
      char &ch = const_cast<char&>(ref[position]);
      return ch;
      
      // 不使用引用时:转型之后得到一个临时副本
      const TextBlock tmp = static_cast<const TextBlock>(*this);
      char &ch = const_cast<char&>(tmp[position]);		
      return ch;			// 返回一个临时对象的引用!!
      

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

    不要使用反向做法——令const版本调用non-const版本!!这可能不经意间改动了不该改动的东西。

猜你喜欢

转载自blog.csdn.net/fcku_88/article/details/88373386