我应该声明任何可以是const const方法的方法

时间:2011-04-18 20:03:09

标签: c++ const-correctness

简单的问题。 Should I declare any method that can be const a const method?这包括不返回任何成员变量的方法,或者返回对成员变量的const引用。是否有任何理由不这样做(除了显而易见的原因,编译器无论如何都会指出)?

5 个答案:

答案 0 :(得分:13)

无法通过指向常量对象的指针调用非const方法。因此,如果方法可以const,则不将其声明为const会对其使用施加人为限制。

除此之外,制作方法const是一个重要的语义细节,可以让用户感受到调用它所带来的效果。

答案 1 :(得分:6)

这似乎是我在这里的录音说明:

  

我应该声明任何可以是const const方法的方法吗?

不,在设计过程中,应该在不同的层面上做出决定。您应该将{em>语义不修改对象的所有方法标记为const。这可能包括一些实际修改某些内部细节的方法,这些内部细节不属于对象的可感知状态(并且这些属性应为mutable)并且可能不包含某些方法不要改变任何东西。

enum impl {                 // different implementations of the algorithm
   one_implementation,
   another_implementation
};
class example {
   mutable std::pair<bool, int> cache;
protected:
   int a, b;
public:
   example( int a, int b ) : cache(), a(a), b(b) {}
   virtual ~example() {}
   void set( int _a, int _b ) { 
      cache.first = false;      // invalidate previous result 
      a = _a;
      b= _b;
   }
   int expensive_calculation() const {
      if ( !cache.first ) {
         cache.second = calculate();
         cache.first = true;
      }
      return cache.second;
   }
   virtual void change_impl( impl x ) {}
private:
   virtual int calculate() const = 0;
};

在当前形式中,您无法更改实现,change_impl是非const的,即使它没有修改任何未标记为const的成员属性,因为语义上它确实发生了变化。

另一方面,expensive_calculation()方法没有语义修改对象的状态,在调用操作之前和之后,可感知状态将是相同的,但是修改cache属性以加快以后的调用(如果状态未更改)。因此,该方法为const,缓存为mutable

答案 2 :(得分:5)

是。根据Effective C ++,“尽可能使用const”。

答案 3 :(得分:2)

如果方法不修改对象的逻辑状态,则应将方法标记为const。这对于对象的客户来说是一项很棒的服务,因为它们可以在给定const引用/指针的情况下最大限度地使用。

答案 4 :(得分:2)

有一种情况我会考虑使用const:基类虚函数。继承类不能通过重写的函数来改变它可能是一件好事,但是一些开发人员可能不同意并且因为这个而真的必须跳过箍。