指针类成员和删除职责

Ren*_*nan 0 c++ pointers memory-management

如果我的类有一个可以由类客户端设置的某种指针,我该如何处理删除?

例:

class A {
};

class B {
public:
   void setA(A* a) {
       this->a = a;
   }
private:
   A* a;
};
Run Code Online (Sandbox Code Playgroud)

该类的析构函数应该如何B?应该删除a吗?正如我所看到的,用户可以通过两种方式设置此指针:

... // Assume B object b being created elsewhere
A aObj;
A* aPtr = new A();

b.setA(&aObj); // It is not OK to use delete, and class member will
               // point to invalid memory location once aObj goes out
               // of scope
b.setA(aPtr);  // Using new will make the pointer available even after
               // this block of code
...
Run Code Online (Sandbox Code Playgroud)

那么删除b的正确方法是什么?我应该总是new在我的set方法中执行吗?

Luc*_*ton 7

怎么应该是B类的析构函数?应该删除吗?

作为该类的作者,决定其语义.不要考虑指针,引用和deletes.从设计的角度思考:A和之间的关系是B什么?B需要什么A

两种常见的关系类型是委托和组合.委托意味着客户端代码使用该setA成员使实例知道B它可能用于进一步使用的其他实例.组合意味着该setA成员用于初始化实例的内部部分.

委派的一种可能实现是使用成员指针.我建议传递一个引用setA来赋值给指针; 它回避了检查的问题,0并使客户端代码明显表明没有所有权问题需要处理.这与多态类型兼容.

组合的一种可能实现是使用A成员,并通过引用传递给const或通过值来分配它.另一个是使用智能指针,特别是如果A要多态使用.通过智能指针传递是最简单的事情 - 但你必须检查0和/或记录演员表.

无论您决定使用什么(无论如何都不必在此列表中),请使用代码作为工具来实现您的目的或设计.不要让代码决定你的想法.

在我的所有示例实现中,您不必在析构函数中执行任何特殊操作.