2017-10-01 19 views
3

私はそれがそのクラスを所有していないし、それがメモリだ管理を担当ませんでしたので、ここまでになるまで他のクラスへの参照を持っていたクラスを持っています。一貫性のない所有権

class MyClass 
{ 
    OtherClass& m_other; 
public: 
    MyClass(OtherClass& other) : m_other(other) {} 
}; 

私はいくつかのケースでMyClassがm_otherの所有者であると私は削除OtherClassにつながる削除を希望状況にただしています。そして、それは所有者ではない場合もあります。この場合

は、両方のケースを表すか、(unique_ptrを有する)の両方のケースをカプセル化する単一のクラスを持っている2つのクラスを持っていることがより適切です。例えば

class MyClass 
{ 
    OtherClass& m_other; // class may or may not be the one we manage. 
    std::unique_ptr<OtherClass> m_managed; // May be null 
public: 
    MyClass(std::unique_ptr<OtherClass> managed) : m_other(*managed), m_managed(std::move(m_managed)) {} 
    MyClass(OtherClass& other) : m_other(other), m_managed() {} 
}; 

class MyClassRef 
{ 
    OtherClass& m_other; 
public 
    MyClassRef(OtherClass& other) : m_other(other) {} 
}; 

class MyClassOwner 
{ 
    std::unique_ptr<OtherClass> m_other; // Never null 
public: 
    MyClassOwner(std::unique_ptr<OtherClass> other) : m_other(std::move(other)) {} 
}; 

これはおそらく、かなり単純な例ですが、分割されたケースを扱う際に一般的には、より良い...これらのケースを処理するための新しいクラスを作成するためにされたりなど、多くをカプセル化します合理的なレベルまで、1つのクラスのケースをカバーします。

編集:第二のオプションに類似している第三のオプションがstd::shared_ptr<T>などを使用することです

class MyClass 
{ 
    std::shared_ptr<OtherClass> m_other; 
public: 
    MyClass(std::shared_ptr<OtherClass> other) : m_other(other) {} 
    MyClass(OtherClass& other) : m_other(std::shared_ptr<OtherClass>(&other, [](OtherClass* p){})) {} 
}; 

私はポインタがスタックに割り当てられたためにオブジェクトを許可するようMyClassはまだ参照を受け入れるようにしたい。注;これはコンストラクタがスタックオブジェクトを削除しないようにカスタムディテクタでshared_ptr<OtherClass>を作成する理由です。

+1

split-classオプションを使用する場合は、両方のタイプを処理できるように、多くのオーバーロードされた機能を作成する必要があります。 –

+0

4番目のオプション:デザインを再確認してください。提供内容は、私たちがここに支援することはできませんが、それはかなり奇抜なデザインと、それは私はこの答えは満足であるかどうかわからないんだけど、良いもの –

答えて

4

他のいくつかのケースでは、所有者でないながらクラスは、いくつかのケースでは所有者であるかもしれとき、あなたはリソースのユニークな所有権を必要とする、std::unique_ptr<T>の代わりに、使用回数を維持する、std::shared_ptr<T>を使用する必要がありますが。

m_otherが指すオブジェクトへのすべての参照がスマートポインタstd::shared_ptr<T>によって維持される限り、オブジェクトを所有するプログラムの部分に関係なく、リソース管理は自動化されます。

+0

だかどうかをチェックするのは価値があります。しかし、他の誰かが同様にそれを所有するかもしれない - 私は、それを理解してきたよう最善として 'のstd :: shared_pt 'の意味論は、I( 'MyClass')は、このオブジェクトの明確な所有者だということです。私が定義しているのは、私がこのオブジェクトを所有しているかもしれないし、所有していないかもしれない場合です。私は、オブジェクトを削除しないように、カスタム削除手段を使用することができます知っているが、それはエラーが発生しやすいようです - そして、特に私の場合、私はへの参照を持っているオブジェクトは、スマートポインタとよく形成していないスタック割り当てられたオブジェクトです。 –

+1

@JacobHullこの場合、スタックオブジェクトでは機能しないため、共有ポインタは使用できません。 (1)スタックオブジェクトを使用しないように切り替える:パフォーマンスの差が小さすぎて測定できない、自動リソース管理で所有権を自動的に処理できる、または(2)独自の所有権管理コードをロールバックする、ポインタと 'bool'をコンストラクタに渡し、従属が所有されているかどうかを示し、所有者のオブジェクトをデストラクタで削除します。 – dasblinkenlight

関連する問題