The solution to this problem is the pre-destruction phase, where you can manually control how the destruction occurs.
Embed your object using the pImpl template. When the packaging object is destroyed, tell pImpl that it will be destroyed before you destroy it.
pImpl can have a virtual PreDestroyable base class that allows child methods to register the PreDestruction that you call during this pre-destruction phase.
class Destroyable { protected: Destroyable() {}; // must be empty virtual ~Destroyable() { Assert(PreDestroyers.empty()); }; void RegisterPreDestroy( std::function<void()> const& func ) { PreDestroyers.push_back(func) ); private: std::vector<std::function<void()>> PreDestroyers; public: // reverse order, reentrant: void PrepareToDie() { while (!PreDestroyers.empty()) { auto f = PreDestroyers.back(); PreDestroyers.pop_back(); f(); } } }; // handles registration: template<typename T> class HasPreDestroyCode: public virtual Destroyable { // TODO: usual CRTP static or dynamic checks: T* self() { return static_cast<T*>(this); } T const* self() const { return static_cast<T*>(this); } HasPreDestroyCode() { RegisterPreDestroy( [&]() { self()->PreDestroy(); } ); } HasPreDestroyCode( HasPreDestroyCode const& other ) { RegisterPreDestroy( [&]() { self()->PreDestroy(); } ); } HasPreDestroyCode( HasPreDestroyCode const& other ) { RegisterPreDestroy( [&]() { self()->PreDestroy(); } ); } private: HasPreDestroyCode& operator=( HasPreDestroyCode const& other ) = delete; }; class Test: HasPreDestroyCode<Test> { public: void PreDestroy() {} };
I wrote this material before C ++ 11, so I have not developed how to handle the movement by creating it. And all this is done at runtime, while it is probably possible to do something like the above, with less runtime data. Something like a list of types in a hierarchy containing pre-destroy code, or something else?
source share