1

現在、既存のクラスのラッパーを作成しています。既存のクラスを直接使用するクライアント コードを変更せずにラッパーを作成する最善の方法は何ですか?

class A
{
public:
    void foo() {}
};

template<typename T>
class Wrapper
{
// ...other wrapper data/functionality...
private:
    T myObject;
};

main()
{
    Wrapper<A> wrappedA;
    wrappedA.foo();
}

msvc でコンパイルがエラー C2039 で失敗する: 'foo' : is not a member of 'Wrapper'

メインのコードを変更せずにテンプレート ラッパー クラスを機能させる最善の方法は何ですか?

  • 選択演算子。オーバーロードできません
  • 型 T へのキャスト演算子を記述しても、コンパイラは選択を行う前にキャストを試行しないため、役に立ちません。
  • 内部の myObject メンバーを返す get 関数を作成できますが、main のクライアント コードを書き直す必要があります。これは、記述しようとしている新しいラッパー クラスを使用せずに myObject を直接使用する既存のコードが多数ある場合には、適切ではありません。

編集

  • myObject を直接使用する既存のクライアント コードを変更せずに、myObject にラッパー クラスを記述したいと考えています。
  • A::foo() は、他の型 T に T::foo() がない可能性があるため、ラッパーに持ち込むことはできません。
4

3 に答える 3

3

Aインスタンス経由で呼び出す必要があります。

wrappedA.myObject.foo();

あなたのラッパーはあまり賢いラッパーではないので、 というインスタンスを保持していることを知る必要がありますmyObject。変換演算子を与えることで賢くすることができます:

template<typename T>
class Wrapper
{
public:
    T myObject;

    operator const T& () const { return myObject; }
    operator T& () { return myObject; }
};

Aこれにより、必要な場所で使用できます。

void bar(const A& a) { a.foo(); } // (make A::foo() a const method)

Wrapper<A> a;
bar(a);  // OK 
于 2013-10-28T07:02:50.427 に答える
2

wrappedA.myObject.foo();の代わりに使用wrappedA.foo();

于 2013-10-28T07:06:06.630 に答える
2

-> を使用してメソッドにアクセスする必要がない場合は、ラップされたクラスへのポインターを返す operator-> を提供します。

template
class Wrapper
{
public:
  T* operator->() { return &myObject; }
  T const* operator->() const { return &myObject; }
...
};

しかし、本当にメソッドにアクセスするためにドットを使用したい場合は、T から Wrapper を派生させることはできますか? (しかし、あなたのクラスはまったくラッパーではありません:D)

于 2013-10-28T07:01:14.547 に答える