0

重複の可能性:
同様の const メンバー関数と非 const メンバー関数の間のコードの重複を削除するにはどうすればよいですか?

次の例では:

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-constoperator[]は独立して実装されます。

デザインに関しては、次のものが必要です。

  • 1) ここのような 2 つの独立した実装
  • 2) もう一方を呼び出す 2 つの関数の 1 つ

解決策 2) の方が優れている場合、指定された例のコードは何でしょうか?

4

3 に答える 3

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_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

于 2012-12-10T02:05:03.417 に答える
1

constness をキャストしないと、いずれかの実装で他方を呼び出すことはできません。これは悪い考えです。

constメソッドは non- constoneを呼び出すことはできません。

非メソッドは、戻り値の型をキャストする必要があるため、constメソッドを呼び出すべきではありません。const

于 2012-12-10T01:27:45.327 に答える
0

残念ながら、「constness」テンプレートは機能しませんが、全体的なアイデアを検討する価値があると思います。

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

とりあえず、些細な関数を2回だけ実装します。コードが 1 ~ 2 行よりも複雑になった場合は、詳細を関数テンプレートに分割し、実装を委任します。

于 2012-12-10T01:32:55.530 に答える