2017-02-18 8 views
-3

は、次のクラスを考えてみましょう:私は次のコードをお持ちの場合のshared_ptrは

class MyInterface1 { 
    ... 
}; 
class MyInterface2 { 
    ... 
}; 
class MyClass : public MyInterface1, public MyInterface2 { 
    ... 
}; 

は:

void MyFunction(shared_ptr<MyInterface1>& out); // returns a make_shared<MyClass> 

shared_ptr<MyInterface1> c1; 
shared_ptr<MyInterface2> c2; 
MyFunction(c1); 
c2 = c1; 

を私はC1にC2を割り当てることができないんです。

また、MyFunction(c2)を呼び出すだけでコンパイルされません。これは、MyClassがMyInterface1とMyInterface2の両方から派生しているため動作すると予想されます。これは、共有する価値のあるコンパイラのバグ(Visual Studio 2015 Update 3)のようです。誰でもこれを再現できますか?

+4

いいえ、これはコンパイラのバグではありません。 –

+5

これは 'shared_ptr'とは何の関係もありません。これは未処理のポインタでも機能しません。 – tkausl

+1

'MyClass'は' MyInterface1'または 'MyInterface2'でも構いませんが、' MyInterface1'と 'MyInterface2 'の間には関係はありません。 – user4581301

答えて

-5

これはrawポインタを使って行うことができますが、shared_ptrを使って行うことはできません。 shared_ptrは使用しないでください:

void MyFunction(MyInterface1* out); // returns a new MyClass() 

MyInterface1* c1; 
MyInterface2* c2; 
MyFunction(c1); 
c2 = (MyInterface2*)c1; 
MyFunction((MyInterface1*)c2); 

これは確かにクリーンで簡単でメンテナンス性が高いです。また、shared_ptrをもう使用していないため、オーバーヘッドが少なくて済みます。パフォーマンスを気にする場合は、shared_ptrを使用しないでください。

+0

複数の理由から最良の選択ではありません。 Cスタイルのキャスティングを避ける - それはあなたを悪くする可能性があります。明示的な所有権のないポインタで新しいオブジェクトを引数で返すことは、ほとんどの場合別の悪い考えです。 – Dusteh

+1

本当に悪いアドバイスです。 Cスタイルのキャストは神のように、「私を信じて、私がやっていることを知っている」と言っている。正しいか間違って起こることがあるので、神が正しいことをより良く希望します。この場合、あなたは神を再生している、あなたは間違っています。 – user4581301

+0

私は実際に解決策を提示した唯一の人であり、他のすべての人がその悪い考えを言っています。その悪い考えは、言語の作成者と一緒に取る。これはスタイルに関する質問ではありませんでしたので、他の場所であなたの "聖なる戦争"を取る...開発者は質問をし、私は実際に答えを出す唯一の人でしたが、誰もが不平を言って、コミュニティに問題があるのだろうか? –

4

MyInterface1およびMyInterface2は完全に無関係のタイプです。オブジェクトがc1で指さという理由だけで、静的なタイプに互換性がありません、あなたは他の

shared_ptr<MyInterface1> c1; 
shared_ptr<MyInterface2> c2; 
MyFunction(c1); 
c2 = dynamic_pointer_cast<MyInterface2>(c1); 

Live Example

この意志に1を割り当てるためにキャストを使用する必要があります両方から継承するランタイム型を持っていますもちろん、実際の動的タイプが*c1の場合は、MyInterface2から継承されている場合にのみ機能します。 dynamic_castと同様に、dynamic_pointer_castは、型が互換性がない場合nullptrを返します。

関連する問題