如何自定义QScopedPointerDeleter以避免调用父类的析构函数



我有两个类A和B,看起来像这个

class A{
public:
~A(){/* do something */};
};
class B : public A{
public:
~B(){/* do something */};
};

当调用~B()时,我希望避免调用~A()。我发现这篇文章说std::shared_ptr可以自定义deleter来控制析构函数。但我正在做一个使用QScopedPointer声明B的Qt项目。现在我的问题是:
如何自定义QScopedPointerDeleter以避免调用父A的析构函数?

好人

不要这样做。用干净的方法解决实际问题。

坏人-我真的很想这么做

警告 请记住,使用这种方法可能会遇到麻烦,例如,通过创建内存泄漏或未定义的行为。

请注意,在不执行父/基析构函数~A的情况下调用子析构函数~B是不可能的:

即使直接调用析构函数(例如obj.~Foo((;(,这个~Foo((中的return语句不将控制权返回给调用者立即:它首先调用所有这些成员和基析构函数。[1]

但是,您可以将~B的逻辑移动到另一个成员函数,并调用该成员函数:

class B : public A{
public:
~B(){/* do something */};
void DestructWithoutParent () {
/* do something */
/* call destructor of members*/
}
};

请注意,现在应该显式调用成员的析构函数(如果有的话(。

现在,您可以手动释放B对象的内存,并调用自定义析构函数(有关更多信息,请参阅此答案以及为什么不应该使用此方法(:

B *b = new B();
b->DestructWithoutParent (); // calls the 'destructor' of B without calling ~A
operator delete(b); // free memory of b

请注意,A(例如A的智能指针成员(拥有的堆内存不会以这种方式释放。它也可能违反A类程序员的假设,可能导致未定义的行为。

将其与QScopedPointer[2]集成:

struct BDeleter {
static inline void cleanup(B *b)
{
b->DestructWithoutParent (); // calls the 'destructor' of B without calling ~A
operator delete(b); // free memory of b
} 
};
QScopedPointer<B, BDeleter> b(new B);

最新更新