【问题标题】:Design : const and non-const accessors interdependance? [duplicate]设计:常量和非常量访问器相互依赖? [复制]
【发布时间】:2012-11-27 10:38:06
【问题描述】:

可能重复:
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 和 non-const operator[] 是独立实现的。

在设计方面是不是更好:

  • 1) 像这里这样的两个独立实现
  • 2) 两个函数之一调用另一个函数

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

【问题讨论】:

  • 在 Effective C++ 第三版(第 3 项)中实际上提到了可以在非 const 版本中执行此操作:return const_cast&lt;Type&amp;&gt;(static_cast&lt;const MyClass&amp;&gt;(*this)[i]); 我认为如果您有其他东西而不是仅仅不过,每行只有一行。
  • @chris 我确实希望您必须查找版本和项目编号。否则有点担心.. :)
  • @Troy,确实,我只记得在其中一本书中读过类似的内容。

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


【解决方案1】:

如果不抛弃 constness,您就不能让任一实现调用另一个实现,这是一个坏主意。

const 方法不能调用非const 的方法。

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

【讨论】:

    【解决方案2】:

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

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

    目前,我只实现两次微不足道的功能。如果代码变得比一两行更复杂,我会将细节分解到函数模板中并委托实现。

    【讨论】:

      【解决方案3】:

      这是一种众所周知且被广泛接受的实现模式,当非常量方法通过其对应的 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_casts 堆积。

      人们可能会想出一个形式上更好的无铸件解决方案来实现

       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 的方法更不优雅。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        相关资源
        最近更新 更多