设计:const和非const访问器相互依赖?

时间:2012-12-10 01:26:01

标签: c++ c++11 const subscript-operator

  

可能重复:
  How do I remove code duplication between similar const and non-const member functions?

在以下示例中:

template<typename Type, unsigned int Size>
class MyClass
{
    public: inline Type& operator[](const unsigned int i) 
    {return _data[i];}

    public: inline const Type& operator[](const unsigned int i) const
    {return _data[i];}   

    protected: Type _data[Size];
};

const和非const operator[]是独立实现的。

在设计方面,最好有:

  • 1)这里有两个独立的实现
  • 2)两个函数中的一个调用另一个

如果解决方案2)更好,那么给定示例的代码是什么?

3 个答案:

答案 0 :(得分:4)

当非const方法通过const对应方实现时,这是一个众所周知且被广泛接受的实现模式,如

 class some_class {

   const some_type& some_method(arg) const
   {
     ...;
     return something;
   }

   some_type& some_method(arg)
   {
     return const_cast<some_type&>(
       const_cast<const some_class *>(this)->some_method(arg));
   }
 };

这是一种非常有效的技术,在方法体相对较重的情况下,基本上没有可比较的(方便的)替代方案。 const_cast的邪恶远小于重复代码的邪恶。

然而,当方法的主体基本上是单行时,最好坚持使用明确相同的实现,只是为了避免这种几乎不可读的const_cast s堆积。

人们可能会提出一个正式更好设计的无演员解决方案,这些解决方案是按照

的方式实施的
 class some_class {

   template <typename R, typename C>
   static R& some_method(C *self, arg)
   {
     // Implement it here in terms of `self->...` and `R` result type
   }

   const some_type& some_method(arg) const
   {
     return some_method<const some_type>(this, arg);
   }

   some_type& some_method(arg)
   {
     return some_method<some_type>(this, arg);
   }
 };

但对我来说,它看起来比使用const_cast的方法更不优雅。

答案 1 :(得分:1)

你不能让任何一个实现在不抛弃constness的情况下调用另一个实现,这是一个坏主意。

const方法无法调用非const方法。

const方法不应调用const方法,因为它需要转换返回类型。

答案 2 :(得分:0)

不幸的是,“constness”模板不起作用,但我仍然认为值得考虑整体想法:

// NOTE: this DOES NOT (yet?) work!
template <const CV>
Type CV& operator[](unsigned int index) CV {
    ...
}

目前,我只实施了两次琐碎的功能。如果代码变得比一行或两行更复杂,我会将细节分解为函数模板并委托实现。