所有权不一致

时间:2017-10-01 22:29:33

标签: c++11 ownership

我有一个课程,直到此时才引用另一个课程,因为它没有拥有该课程,也不负责管理它的内存。

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>而不删除堆栈对象的原因。

1 个答案:

答案 0 :(得分:4)

如果在某些情况下该类可能是所有者,而在某些其他情况下,该类不是所有者,则应使用std::shared_ptr<T>来维护使用计数,而不是{ {1}},需要资源的唯一所有权。

只要std::unique_ptr<T>指向的对象的所有引用都通过m_other智能指针进行维护,资源管理就会自动为您完成,无论程序拥有该对象的部分如何。