OK、共有ポインターの使用を開始し、可能な限り共有ポインターを渡します。生ポインタへの変換はもうありません。この特定のケースを除いて、これはうまく機能します。
次のように、別のクラスのオブザーバーでもあるクラスがあるとします。
class MyClass : public IObserver
{
public:
MyClass (std::shared_ptr<SomeOtherClass> otherClass);
void DoSomethingImportant();
private:
std::shared_ptr<SomeOtherClass> m_otherClass;
};
このクラスは、私のアプリケーションでは次のように使用されます。
std::shared_ptr<MyClass> myInstance(new MyClass(otherInstance));
...
myInstance->DoSomethingImportant();
MyClass は、別のクラスへの共有ポインターを取得し、これを m_otherClass データ メンバーに格納します。DoSomethingImportant メソッドでは、MyClass インスタンスは、次のように m_otherClass のオブザーバーとして自身を登録するなど、多くの重要なことを行います。
m_otherClass->registerObserver(this);
問題は、registerObserver メソッドが次のように定義されていることです。
void registerObserver (std::shared_ptr オブザーバー);
共有ポインターが必要ですが、「this」は生のポインターであり、共有ポインターではありません。
これを解決するには、次の 3 つの方法があります。
- 通常のポインターを共有ポインターに変換するトリックを見つけます (質問convert pointer to shared_ptr を参照)。しかし、その質問への回答は共有ポインターをコピーすることのみを示唆しており、ポインターを共有ポインターに実際に変換する方法については示唆していません。
- 「myInstance->DoSomethingImportant(myInstance);」のように、自分自身への共有ポインタをメソッドに渡します。これは少しばかげているようです。
- オブザーバー部分を別のクラスに入れます。これはやり過ぎのように見え、クラスを理解しにくくする可能性があります。
この問題は、共有ポインタが C++ への単なるアドオンであることを明らかにしています (C# (または一般的に .Net) や Java などの他の言語/環境では同じ問題があるとは思いません)。
この状況を処理する方法に関する他の提案やトリックはありますか?