我有一个课程,直到此时才引用另一个课程,因为它没有拥有该课程,也不负责管理它的内存。
class MyClass
{
OtherClass& m_other;
public:
MyClass( OtherClass& other ) : m_other( other ) {}
};
但是,在某些情况下MyClass
是m_other的所有者,我希望删除导致删除OtherClass
。在某些情况下,它不是所有者。
在这种情况下,让两个类表示两种情况或者使用一个封装两种情况的类(使用unique_ptr)更合适。 e.g。
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 ) ) {}
};
VS
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() {}
};
这可能是一个相当简单的例子,但一般来说,在处理拆分案例时,最好是创建新类来处理这些案例......或者将尽可能多的案例封装在一个类中 - 达到合理的水平。 / p>
编辑:与第二个选项类似的第三个选项是使用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>
而不删除堆栈对象的原因。
答案 0 :(得分:4)
如果在某些情况下该类可能是所有者,而在某些其他情况下,该类不是所有者,则应使用std::shared_ptr<T>
来维护使用计数,而不是{ {1}},需要资源的唯一所有权。
只要std::unique_ptr<T>
指向的对象的所有引用都通过m_other
智能指针进行维护,资源管理就会自动为您完成,无论程序拥有该对象的部分如何。