class ClassA
{
public:
ClassA(ClassB *p) b(p){}
~ClassA(){delete b;}
ClassB *b;
};
这种设计是否好呢?
class ClassA
{
public:
ClassA(ClassB *p) b(p){}
~ClassA(){delete b;}
ClassB *b;
};
ClassA object1( new ClassB() ); //object1 takes ownership of the object
ClassA object2( object1 ); //object2 takes ownership of the same object
// now first object2 is destroyed and deletes the object
// then object1 is destroyed and double-delete happens
您的意思是:
class ClassA {
ClassB *b;
public:
ClassA(ClassB * p) {b = p;}
~ClassA() {delete b;}
};
这不是一个好的设计。创建者应该是删除者。
从技术上讲,这并没有什么特别的问题 - 当创建ClassB实例时(即在需要ClassA之前),您已经将其所有权传递给了ClassA实例(但一旦创建了ClassA,则它将成为ClassB的所有者)。
它是否是一个好的设计,取决于它所应用的上下文。例如,ClassA接管ClassB是否有意义?是否应该使用智能指针而不是“普通的”指针?
正如其他人所说,最好通过使用智能指针或在创建对象的同一级别上删除对象来避免这种情况...或者根本不使用指针。
同时,我不认为转移对象所有权一定是不良设计,只要在文档中明确告知ClassA用户即可。在编写函数时,我遇到了类似的情况,这些函数接受一个指向对象的指针并对其进行复制构造以供自己使用。在需要的情况下,我倾向于使用“参数复制语义”之类的注释来告诉调用者“我返回后你可以随意处理这个对象...我有自己的副本”。
如果您正在使用裸指针,则考虑建立这些调用者合同非常重要。
new
和delete
在同一级别上发生)。然而,也有一些例外情况;例如,智能指针提供了一个原始指针,然后接管对象的所有权,因此它们负责在不再需要时调用delete
。
ClassA
正在接管由*p
指针给出的ClassB
实例的情况。请仅返回翻译后的文本内容,不要进行解释。 - erjot