Specifically, in a library, I have a memory pool that overrides the behaviour of new and delete for certain classes. I want users of the library to be able to call delete on instances of those classes, but I need to keep the instances alive until a specific cleanup action at a later time. Is this at all possible while letting the users use regular new/delete? Some way to override the default behaviour of calling the destructor?
Short answer: no.
Calling delete
always triggers a call to the destructor, and after that a call to operator delete
, the same way as calling new
first calls the corresponding operator new
and then runs the constructor of the object.
If you want to prevent your users from destroying the objects you have to somehow prevent them from a) calling delete on raw pointers and b) construct them on the stack.
If you want to keep the instances alive it sounds like you want to manage their lifetimes, so the natural way would be to also create the objects inside your library in the first place. In addition, having plain delete
calls in the code is considered bad style these days anyway, as there are smart pointers available who do those calls automatically.
So what you could do is add creator functions to your library which return some kind of smart pointers. Those could be either shared_ptr
or unique_ptr
s with a special deleter which does not really delete the object but pass it back to your library to be cleaned up later.
Use smart pointers instead of new
/delete
(which is good practice anyway).
Use a custom deleter that moves ownership of the object to a list of "waiting to be cleaned up" objects.
For examples of smart pointers, refer to std::unique_ptr
and std::shared_ptr
.
Another option (which is more work and harder to get right) is to only store the objects in containers that use custom allocators, and have the allocator's destroy
and deallocate
functions do the "move to a staging area for cleanup instead of actually destroying it" part. I would recommend the smart pointer with custom deleter approach, not the allocator one.
Both these options (custom deleters and custom allocators) allow you to control the exact behaviour when an object is "destroyed", separating the actual end of the object's lifetime from the moment when users dispose of it, which cannot be done with the delete
operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With