私はそれがそのクラスを所有していないし、それがメモリだ管理を担当ませんでしたので、ここまでになるまで他のクラスへの参照を持っていたクラスを持っています。一貫性のない所有権
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>
を作成する理由です。
split-classオプションを使用する場合は、両方のタイプを処理できるように、多くのオーバーロードされた機能を作成する必要があります。 –
4番目のオプション:デザインを再確認してください。提供内容は、私たちがここに支援することはできませんが、それはかなり奇抜なデザインと、それは私はこの答えは満足であるかどうかわからないんだけど、良いもの –