Reputation: 735
class System
{
public:
virtual ~System() final { Shutdown(); };
virtual void Shutdown() = 0;
}
class DerivedSystem : public System
{
public:
virtual void Shutdown() override;
private:
Object* MySelfAllocatedObj;
}
Here is my use case,
I have a manager that holds a list of System* registered by various other "modules", each of those System* are actually derieved classes, unknown to the System Manager.
Those modules will Request a Shutdown() when their respective System* should end/die.
So, if one of those DerivedSystem has a MySelfAllocatedObj (ptr) and destroys it as part of Shutdown(), would my memory be cleaned properly using the current architecture?
I'm doing so to limit the number of "destruction" functions ie Destructor/Shutdown, but do not want to expose the destructor to the "module requesting that DerivedSystem)
Extra : What would happen if a DerievedSystem class was to declare a destructor?
Edit : Added the : public System (inheritance)
The question is not if I should or not, the question is, Would my memory get cleaned properly either being destroyed by the Manager which does
delete System*
or by the requesting module (3rd party) calling
SystemManager->RequestShutdown(SystemID...) { System->Shutdown()};
Would both path, end up with the same "memory cleared" or would I miss something?
The point is to not duplicated code in those 2 functions.
Upvotes: 0
Views: 134
Reputation: 238421
Within a destructor, the life time of any derived object has already ended, just like within the constructor, the life time of any derived object has not yet begun. Call to a virtual function within destructor (or constructor) will be dispatched statically, as there is no derived object anymore (or no derived object exists yet, in case of constructor) to which it could be dispatched to dynamically. Unless you define System::Shutdown
, the program is unlikely to link succesfully.
Furthermore, declaring the destructor of the base final
will prevent you from deriving such base, since even the implicitly generated destructor of the derived class will be an "override".
Would my memory get cleaned properly either being destroyed by the Manager
delete System*
Your pseudocode is unclear, but from the description I understand that you delete a pointer of type System*
No, because 1. DerivedSystem::shutdown
is never called and because 2. DerivedSystem
is ill-formed because it overrides the final destructor and the program is unlikely to compile.
SystemManager->RequestShutdown(SystemID...) { System->Shutdown()};
This, will call DerivedSystem::shutdown
, so it should work in that regard. The ill-formedness of the class is still a problem though.
Those modules will Request a Shutdown() when their respective System* should end/die.
I'm doing so to limit the number of "destruction" functions ie Destructor/Shutdown
If you want to limit the number of destruction functions, a simple solution is to not provide a Shutdown
function at all, but instead have the systems destroy their respective system, when it should die.
If you really need a separate Shutdown
function - which I don't recommend - and you want to reuse it in the destructor, then you need to call it in the destructor of each derived class.
PS. Explicit delete, and bare pointers to owned resources are very error prone. It's better to use smart pointers instead.
Upvotes: 3