1

クラスが与えられたとしましょうABそれへのポインタを小さなクラス、ある種のスマートポインタにラップしたいのですが、aB*が自動的にに変換されるという制約があるA*ため、すでにを使用しているコードを書き直す必要はありませんA*

したがってB、次のようにコンパイルするように変更したいと思います...

struct A {
  void foo() {}
};

template <class K>
struct B {
  B(K* k) : _k(k) {}
  //operator K*() {return _k;}
  //K* operator->() {return _k;}
private:
  K* _k;
};

void doSomething(A*) {}

void test() {
  A a;
  A* pointer_to_a (&a);
  B<A> b (pointer_to_a);
  //b->foo();             // I don't need those two...
  //doSomething(b);

  B<A>* pointer_to_b (&b);

  // Following represents existing code I don't want to change...
  pointer_to_b->foo();       // 'foo' : is not a member of 'B<K>'
  doSomething(pointer_to_b); // 'doSomething' : cannot convert parameter 1 from 'B<K> *' to 'A *'
}

Bから継承することAはオプションではないことに注意してください(のインスタンスAは私の制御できない工場で作成されます)...

出来ますか?

ありがとう。

4

6 に答える 6

3

pointer_to_b の型は、変更できない型である B へのポインターです。コンパイラによって実装されます。

(*pointer_to_b)->foo() を実行できます。これは正しいことを行います (オーバーライドされた operator->() があると仮定します)。ただし、pointer_to_be を渡すと、他のコードが正しいことを実行できなくなります。

また、特定のユースケースによっては、B の operator& をオーバーライドして A* を返すことができることも付け加えておきます。これにより、問題が解決する可能性があります。

于 2010-04-26T17:15:45.933 に答える
2

のような機能get()boost::shared_ptrどうですか?

template <class K>
struct B {
  B(K* k) : _k(k) {}
  K* get() { return _k;}
private:
  K* _k;
};

次に、次のように使用できます。

pointer_to_b->get()->foo();      
doSomething(pointer_to_b->get());
于 2010-04-26T17:18:18.017 に答える
0

Aから継承するBオプションであり、これはコンパイルされます(少なくともVS 2008):

struct A { 
  void foo() {} 
}; 

template <typename  T> 
struct B : T
{ 
  B(const T& t) : T(t) 
  {} 
}; 

void doSomething(A*) {} 

void test() { 
  A a; 
  B<A> b (a); 

  B<A>* pointer_to_b (&b); 

  // Following represents existing code I don't want to change... 
  pointer_to_b->foo();       
  doSomething(pointer_to_b); 
}
于 2010-04-26T19:01:13.967 に答える
0

あなたがコメントアウトした演算子は、あなたstruct Bが望むことをさせるべきであるように見えます...なぜ彼らはコメントアウトされているのですか? コメントが外されていると機能しませんか? そうでない場合は、エラーを投稿できますか?

于 2010-04-26T17:21:52.793 に答える
0

これは私の観点からはうまくいくはずです

struct A {
  void foo() {}
};

template <class K>
struct B {
  B(K* k) : _k(k) {}
  operator K*() {return _k;}
  K* operator->() {return _k;}
private:
  K* _k;
};

void doSomething(A*) {}

void test() {
  A a;
  A* pointer_to_a (&a);
  B<A> pointer_to_b (pointer_to_a);

  // Following represents existing code NOT CHANGED
  pointer_to_b->foo();       
  doSomething(pointer_to_b);

}
于 2010-04-26T19:51:10.213 に答える
0

問題を回避する方法を思い出すと、shared_ptrあなたが持っていると思うのはshared_ptr*shared_ptrオブジェクトを決して通過させないということです。operator->オブジェクトへのポインターではなく、オブジェクトで呼び出されているため、このように機能します。B<A>の代わりに回ることをお勧めしますB<A>*。ラッパー クラスが A へのポインターを表している限り、それがポインターであるかどうかは誰が気にする必要はありません。

于 2010-04-26T17:45:32.393 に答える