C++11 所有权不一致

C++11 所有权不一致,c++11,ownership,C++11,Ownership,我有一个类,到目前为止,它引用了另一个类,因为它不拥有这个类,也不负责管理它的内存 class MyClass { OtherClass& m_other; public: MyClass( OtherClass& other ) : m_other( other ) {} }; 但是,在某些情况下,MyClass是m_other的所有者,我希望删除导致删除OtherClass。在某些情况下,它不是所有者 在本例中,是使用两个类来表示这两种情况,还是使用一个类来

我有一个类,到目前为止,它引用了另一个类,因为它不拥有这个类,也不负责管理它的内存

class MyClass
{
    OtherClass& m_other;
public:
    MyClass( OtherClass& other ) : m_other( other ) {}
};
但是,在某些情况下,
MyClass
是m_other的所有者,我希望删除导致删除
OtherClass
。在某些情况下,它不是所有者

在本例中,是使用两个类来表示这两种情况,还是使用一个类来封装这两种情况(使用唯一的_ptr)更合适。e、 g

类MyClassRef
{
OtherClass&m_other;
公众的
MyClassRef(OtherClass&other):m_other(other){}
};
类MyClassOwner
{
std::unique_ptr m_other;//从不为null
公众:
MyClassOwner(std::unique_ptr other):m_other(std::move(other)){}
};
vs

class-MyClass
{
OtherClass&m_other;//我们管理的类可能是,也可能不是。
std::unique_ptr m_managed;//可以为空
公众:
MyClass(std::unique_ptr managed):m_other(*managed),m_managed(std::move(m_managed)){}
MyClass(OtherClass&other):m_other(other),m_managed(){}
};
这可能是一个相当简单的示例,但一般来说,在处理拆分案例时,是否最好创建新类来处理这些案例。。。或者将尽可能多的案例封装在一个类中—达到合理的级别

编辑:与第二个选项类似的第三个选项是使用
std::shared\u ptr

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 ){} ) ) {}
};
class-MyClass
{
std::共享的ptr m_其他;
公众:
MyClass(std::shared_ptr other):m_other(other){}
MyClass(OtherClass&other):m_other(std::shared_ptr(&other,[](OtherClass*p){})){}
};

注意,我希望
MyClass
仍然接受引用,以允许指针堆叠分配的对象;这就是为什么构造函数创建了一个带有自定义删除器的
共享\u ptr
,以不删除堆栈对象。

当类在某些情况下可能是所有者,而在某些情况下不是所有者时,您应该使用
std::shared\u ptr
,它维护使用计数,以代替
std::unique\u ptr
,这需要资源的唯一所有权


只要对
m_other
指向的对象的所有引用都通过
std::shared_ptr
智能指针进行维护,无论程序中拥有该对象的部分是什么,资源管理都将为您实现自动化。

如果您选择拆分类选项,然后您必须创建大量重载功能才能处理这两种类型。第四个选项:仔细检查您的设计。提供的细节不允许我们在这里提供帮助,但这是一个相当不寻常的设计,因此值得检查它是否是一个好的我不确定这个答案是否令人满意。据我所知,
std::shared\u pt
的语义是,我(
MyClass
)是这个对象的明确所有者,但其他人也可能拥有它。我定义的是一个我可能拥有或不拥有这个对象的情况。特别是在我的例子中,我引用的对象是一个堆栈分配的对象,它与智能指针不匹配-我知道我可以使用自定义删除器不删除该对象,但这似乎很容易出错。@在这种情况下,您不能使用共享指针,因为它们不适用于堆栈对象。这里至少有两种方法:(1)放弃使用堆栈对象:性能差异应该太小,无法测量,而自动化资源管理可以让您自动处理所有权,或者(2)滚动您自己的所有权管理代码-将指针和
bool
传递给构造函数,指示依赖项是否拥有,并在析构函数中删除拥有的对象。
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 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 ){} ) ) {}
};