我有两个类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);