Reputation: 340
I have 2 classes A and B, which looks like this
class A{
public:
~A(){/* do something */};
};
class B : public A{
public:
~B(){/* do something */};
};
I want to avoid calling ~A()
when ~B()
is called. I found this post said that std::shared_ptr
can customize deleter to control destructor. But I'm working on a Qt project which uses QScopedPointer
to declare B.
Now my question is:
How to customize the QScopedPointerDeleter
to avoid calling destructor of parent A?
Upvotes: 0
Views: 203
Reputation: 11064
Don't do it. Solve the actual problem in a clean way.
WARNING Keep in mind that you may get in trouble using this approach, f.ex. by creating memory leaks or undefined behavior.
Note that calling the child destructor ~B
, without executing the parent/base destructor ~A
isn't possible:
Even when the destructor is called directly (e.g. obj.~Foo();), the return statement in ~Foo() does not return control to the caller immediately: it calls all those member and base destructors first. [1]
However, you can move the logic of ~B
to another member function and call that one instead:
class B : public A{
public:
~B(){/* do something */};
void DestructWithoutParent () {
/* do something */
/* call destructor of members*/
}
};
Note that you should now call the destructor of your members (if any) explicitly.
Now you can release the memory of your B
object manually and call your custom destructor function (see this answer for more information and why you shouldn't use this approach):
B *b = new B();
b->DestructWithoutParent (); // calls the 'destructor' of B without calling ~A
operator delete(b); // free memory of b
Note that the heap memory owned by A
(f.ex. by smart pointer members of A
), isn't released in this way. It may also violate the assumptions made by the programmer of class A, possibly resulting in undefined behavior.
Integrating this with 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);
Upvotes: 1