C++ Base class destrutor order problem - c++

Does anyone know any trick I could use to keep the Derived class until the base class destructor have been called?
i.e:
#include <iostream.h>
class Base
{
public:
Base(){ cout<<"Constructor: Base"<<endl;}
virtual ~Base(){ cout<<"Destructor : Base"<<endl;}
};
class Derived: public Base
{
//Doing a lot of jobs by extending the functionality
public:
Derived(){ cout<<"Constructor: Derived"<<endl;}
~Derived(){ cout<<"Destructor : Derived"<<endl;}
};
void main()
{
Base *Var = new Derived();
delete Var;
}
This will result in Derived class to be destroyed, then Base class will be destroyed.
The reason I need something like this is I have a custom Event(signal/slot) class.
The Event class provide an Observer class.
If I define :
class A : public Event::Observer
and then delete an instance of class A, when the ~Observer automatically remove any signal connected to this observer.
But since Class A is destroyed before the Observer, if something on a different thread call a slot on A after ~A and before ~Observer get called. Everything goes to hell...
I can always call the Observer.release method from the ~A, which fix the timing issue. But it was cleaner if I wouldnt need to.
Any ideas?

You definitely don't want to change destruction order, which is good, because you can't.
What you really want to do is to dispose/disconnect/shutdown the Observer.
What I would do is add this to your Event::Observer class:
void Event::Observer::Shutdown()
{
if(!isShutdown)
{
//Shut down any links to this observer
isShutdown = true;
}
}
void ~Event::Observer()
{
Shutdown();
//rest of Event::Observer destruction
}
and then:
~A()
{
Shutdown();
//clean up any other A resources
}
If you did something like IDisposable suggested by David, that would work too -- just call Observer::Dispose() in your destructor for class A.
My code all assumes that you have only a single thread accessing these objects. Thread synchronization is an entirely separate subject.

Destructors work as they are expected to do and you should not touch them (actually, you can't change the calling order). As for your task - you need proper threads synchronization. As a simplest solution: unsubscribe your observer before deleting it.

I suggest you either implement reference counting or an IDisposable interface and use it as a convention amongst your clients. Whether or not you call Observer::Release() in your A::dtor(), YOu're talking about having a different thread come in and call a method on an object that is being destroyed. That is definitely a race condition, you should never have code from another thread asynchronously executing on a method on an object that is being destroyed.
With reference counting, the event subscriber objects don't get deleted until they are unregistered. With an IDisposable pattern, you make sure to remove any references to an object before the destructor is called. Either could be appropriate depending on your architecture.

Base class destructor always gets called after derived class destructor. You mustn't call any of object's methods from other threads after object's destructor begins execution (regardless of whether it has a base class or not). I'd suggest using a new class that works as a container for class Base instances and implements a safe access to Base's objects (you probably need to use one of synchronization objects to implement id).

You cannot change the order of destruction in an inheritance relationship and that's good (what would a Derived be once its Base was destroyed?. However, you can change the relationship.
For example you could always wrap Derived in a class (template) which calls release() first before destroying Derived.

It's a typical race condition, it's just that this one is glaring.
There are obviously several methods at your disposal. You could for example have a mutex in the Base class and lock it as soon as you enter the destructor of the most derived class... however as you noted it's difficult.
I would suggest making the destructor protected (for each class in the hierarchy) and have a method to invoke for destruction (objects cannot be allocated on the stack any longer), then overload delete for the Base class, and have it unregister your object first before destroying it by calling this special method.
The only issue is that anyone not respecting the make your destructor protected bit will screw things up.
On the other hand, you could also NOT use inheritance, and prefer composition instead. This would allow you to control the destruction order of the various attributes.

Related

Is it a good idea to make an destructor protected to disable delete calls via a base class with virtual functions

I work within an environment where I know that all child classes of an abstract base class will never be deleted via a pointer to this abstract base class. So I don't see the need to have this base class to provide with an virtual destructor. Therefore I make the destructor protected, which seems to do what I want.
Here is a simplified example of this:
#include <iostream>
struct Base
{
virtual void x() = 0;
protected:
~Base() =default;
};
struct Child: Base
{
void x() override
{
std::cout << "Child\n";
}
};
int main()
{
// new and delete are here to make a simple example,
// the platform does not provide them
Child *c = new Child{};
Base *b=c;
b->x();
// delete b; // does not compile, as requested
delete c;
return 0;
}
Is it sufficient to make the destructor protected to be save against unwanted base class deletions, or do I miss something important here?
Is it a good idea to [...]
From a safety point of view I answer with a clear 'no':
Consider the case that the child class is inherited again – maybe someone else than you does that. That person might overlook that you violated good practice in Base and assume that the destructor of Child already is virtual – and delete GrandChild via pointer to Child...
To avoid that situation, you could
make the destructor virtual in Child again – so in the end, nothing gained anyway.
or declare Child final, imposing quite some limits that most likely are meaningless from any other point of view.
And you'd have to opt for one of these for any derived class. All for avoiding a single virtual function call on object deletion?
How often would you do that at all? If frequency of object deletion really is an issue, then consider the overhead of allocating and freeing the memory again. In such a case, it's most likely more efficient to allocate memory just once (sufficently large and appropriately aligned to hold any of the objects you consider to create), do placement new and explicit destructor calls instead and finally free the memory again just once when you are done completely and don't need it any more. That will compensate the virtual function call by much...

How to prevent call function call on instance of subclass that is being destroyed

I just had to put in a fix for a difficult-to-find error, but I am not happy about the fix. Our application is C++ running in Windows, and the error was a pure virtual call crash. Here is some background:
class Observable
{
public:
Observable();
virtual ~Observable();
void Attach(Observer&); // Seize lock, then add Observer to the list
void Detach(Observer&); // Seize lock, then remove Observer from the list
void Notify(); // Seize lock, then iterate list and call Update() on each Observer
protected:
// List of attached observers
};
class Subject : public Observable
{
// Just important to know there is a subclass of Observable
}
class Observer
{
public:
Observer();
virtual ~Observer(); // Detaches itself from the Observable
void Update() = 0;
};
class Thing : public Observer
{
public:
void Update(); // What it does is immaterial to this question
};
Because this is a multi-threaded environment, there are locks in place for Attach(), Detach(), and Notify(). Notify() seizes the lock and then iterates the list of observers and calls Update() on each one.
(I hope this is enough of a background without having to post the complete body of code.)
The problem arose when an observer was being destroyed. On destruction, the Observer detaches itself from the Observable. At the same time, in another thread, Notify() is being called on the Subject. My original thought was that we were protected because of the locks in Detach() (called on destruction of the Observer), and Notify(). However, C++ destroys the subclass first, then the base class. This meant that, before the lock in Detach() was obtained which would have prevented the Notify() function from continuing, the implementation of the pure virtual Update() function was destroyed. The Notify() function continued (because it had already obtained the lock) and attempted to call Update(). The result is a crash.
Now, here is my solution, which works, but gives me a queasy feeling. I changed the Update() function from being pure virtual to just being virtual and provided a body that did nothing. The reason this bothers me is that Update() is still being called, but on a partially destructed object. In other words, I am getting away with something, but I am not wild about the implementation.
Other options discussed:
1) Move the locking into the subclasses. Not desirable because it forces the developer of each subclass to duplicate the logic. And if he omits the locking, bad things can happen.
2) Force the destruction of the observer to occur via a Destroy() function. Honestly, I wasn't sure how to implement this for stack-based objects.
3) Have the subclass call a "PreDestroy()" function in its destructor to notify the base class that destruction is imminent. I wouldn't know how to force this, and forgetting it could lead to hard-to-find runtime errors.
Can anyone offer any suggestions as to a better way to protect against these types of crashes? I have this unpleasant feeling that I am missing the elephant in the room.
JAB
This problem is an illustration of a more general consequence of multi-threaded design: no object that is affected by multiple threads can provide a guarantee of no concurrent access to itself at any point in time. This consequence is the elephant in the room that is giving you the unpleasant feeling you describe at the end of your question.
In short, your problem is that Attach(), Detach(), and Notify() are responsible for both grabbing the appropriate lock and doing their thing. They need to be able to assume the lock is grabbed before they are called.
Unfortunately, the solution requires a more complicated design. It is necessary for some single source that is independent of your objects (or classes) to mediate the construction, updating (including attaching and detaching), and destruction of all your objects. And it is necessary to prevent any of those processes from occurring independently of the mediator.
It is a design choice whether you prevent those processes by technical means (e.g. access control, etc) or simply state policies that all your types must comply with. That choice depends on whether you can rely on your developers (including yourself) to follow policy guidelines.
About your solutions:
Not good, because of the reasons you give.
Ok. Additionally, define ~Observer() as protected (as any other destructor of derived classes) to avoid calling delete directly and write a member void Destroy(). The problem is that it will not work for automatic (local) variables. Actually, with a protected destructor you will not be able to declare local variables.
You probably mean calling PreDestroy() from the destructor of each subclass destructor. The problem will be not to forget it (you can assert that it has been called from ~Observer()) and if you have several levels of inheritance.
About your original solution:
Making Update() a callable virtual function seems to work, but it is technically wrong. While one thread is calling the virtual Update(), using the vtable pointer, another thread is calling ~Thing() and updating the vtable pointer to that of Observer(). The first thread holds the lock, but the second one does not, so you have a race.
My advice would be use option 2 unless you are very fond of automatic instances of subclasses of Observer.
If you are willing, you could try with templates:
template<typename O>
class ObserverPtr : Observer
{
public:
ObserverPtr(O *obj)
:m_obj(obj)
{}
void Update()
{
m_obj->Update();
}
~ObserverPtr()
{
PreDestroy();
delete m_obj;
}
private:
O *m_obj;
};
And then Thing will not derive from Observer.
You can also create alternative variants of this template:
to hold a reference to the real observer instead of a pointer (O &m_obj;). No use of delete.
to define the real observer as an actual member (O m_obj;). No dynamic allocations.
to hold a smart pointer to the real observer.
I think that unless you mandate to call Detach from the derived class destructor, it will not have an easy solution.
One solution which comes into my mind might be to utilize an extra "wrapper" which will take care of de-registration (and might actually do the registration as well).
Something like this (for example):
class ObserverAgent;
// the wrapper class - not virtual
class Observer
{
public:
Observer(Observable &subject, ObserverAgent &agent)
: _subject(subject), _agent(agent)
{
_subject.Attach(*this);
}
~Observer()
{
_subject.Detach(*this);
}
void Update()
{
_agent.Update();
}
private:
Observable &_subject;
ObserverAgent &_agent;
};
// the actual observer polymorphic object
class ObserverAgent
{
public:
ObserverAgent();
virtual ~ObserverAgent();
protected:
// only callable by the Observer wrapper
friend class Observer;
virtual void Update() = 0;
};
class Thing : public ObserverAgent
{
public:
virtual void Update();
};
The use is then indeed more convoluted:
Subject s;
{ // some scope
Thing t;
Observer o(s, t);
// do stuff
} // here first Observer is detached and destroyed, then Thing (already unregistered)
Note that you cannot Attach/Detach Thing (ObserverAgent) directly, only through Observer (because Observable takes the Observer, not the ObserverAgent).
Perhaps it could be possible to wrap it in a single class for simpler use (Agent being an inner class of the Observer), however then there might be problems with the lifetime of the agents (as the destruction of the Observer would have to be virtual again).
Why not expose the lock as protected in Observable? Observable::~Observable acquires the lock if it's not acquired already by this thread, then goes on with the cleanup. Meanwhile EVERY subclass of Observable acquires the lock in its dtor without further releasing it (which is only done in ~Observable itself).
Frankly, in this design the simplest and the most consistent solution seems to manually Detach() each Observer at the very start of the most derived class' destructor. I don't see how this can be automated, and since something has to be done at the dawn of destruction, why not detachment.
...Well, if we don't need to go deeper:
template<class Substance> struct Observer {
Observer(Observable &o): o(o) { o.attach(s); }
~Observer() { o.detach(s); }
Substance &subst() const { return s; }
private:
Observable &o;
Substance s;
};
struct ThingSubst { void update(); long stats(); };
typedef Observer<ThingSubst> Thing;
Observable o;
Thing thing(o);
std::cout << thing.subst().stats() << std::endl;

Call destructor of derrived class only

Looking at the C++ language standard, is there any way to call only derived class destructor, without calling destructor of the base class?
So, for classes
class Base { public: virtual ~Base() {} };
class Derived : public Base { public: ~Derived();};
if would be possible to write code like
Base *basePtr = new Derived();
//do something with basePtr
// Now somehow destroy Derived while keeping Base - call ~Derived() only,
// line below however will call both ~Derived() and ~Base() - how it can be done?
dynamic_cast<Derived*>(basePtr)->~Derived();
So, after execution of the code above basePtr will point to Base object only, like if it was created by
Base *basePtr = new Base();
plus any modifications to the Base object caused by manipulating basePtr between calling new Derived() and destroying Derived class?
Or, is this forbidden and it is impossible to do?
No, this is not possible. The standard demands that the destruction of a Derived object destroys the whole object, including the Base subobject. Anything else would not be a destruction according to C++'s understanding of object lifetime.
Depending on what you want to achieve, consider to copy the Base out of the derived first
std::unique_ptr<Base> basePtr(new Derived());
//do something with basePtr
basePtr.swap(std::unique_ptr<Base> (new Base(*basePtr))); //splice the Base part out of the derived object
//basePtr now points to the spliced Base object.
Another approach would be to hold the additional members that derived has in a boost::optional (or just a pimpl) and reset that to get a "stripped" Derived object that still has its Base class part. This will however not affect virtual function dispatch.
As you have formulated the question, it is not possible to achieve what you are asking for. Unless you have a memory leak, the only case when explicitly calling a destructor does not lead to undefined behavior is if the object was created by placement new. Even then, calling the destructor will automatically call the destructor of every member and base class.
This is as it should be. Otherwise it would be very difficult to write a correct container class or memory manager.
The standard says that the lifetime of an object ends as soon as it enters the destructor. It does not become a base class object. It ceases to be an object, entirely. Also, if this was not the case, what would be the status of a class deriving from multiple bases after such a trick?
Ultimately, the "need" for such a functionality is a sign of bad design. I would guess your use case more likely requires composition. See if you can't solve it with a new class which holds one instance of what is currently the base class and one optional, replaceable component of (a smart pointer to) some dummy class which serves as an interface to and the new common base of your current derived classes. That way you can remove (and destruct) those sub objects without touching the base.
Destructors are called automatically in the reverse order of construction. I do not believe there is any way around this.
This is not possible to do unless your derived class has nothing to do with your base class.
Destructors are called in automatic way.Explicitly call destructor may result in undefined behavior.

C++ virtual method not working

Given the following example:
class BaseClass
{
BaseClass()
{
};
virtual ~BaseClass()
{
this->Cleanup();
};
virtual void Cleanup()
{
// Do cleanup here.
};
};
class Level1DerivedClass : public BaseClass
{
Level1DerivedClass()
{
};
virtual ~Level1DerivedClass()
{
};
virtual void Cleanup()
{
// Call my base cleanup.
BaseClass::Cleanup();
// Do additional cleanup here.
};
};
class Level2DerivedClass : public Level1DerivedClass
{
Level2DerivedClass()
{
};
~Level2DerivedClass()
{
};
void Cleanup()
{
// Call my base cleanup.
Level1DerivedClass::Cleanup();
// Do additional cleanup here.
};
};
main()
{
Level2DerivedClass * derived2 = new Level2DerivedClass();
delete derived2;
return 0;
}
When I delete my derived class reference, I would EXPECT the flow would be as follows:
Level2DerivedClass destructor is executed.
Because Level1DerivedClass destructor is virtual, it would be executed.
Because BaseClass destructor is virtual, it would be executed.
Because BaseClass::Cleanup and Level1DerivedClass::Cleanup are both virtual, the call from the BaseClass 'this' pointer in the BaseClass destructor would executed the implementation of the most derived class - Level2DerivedClass::Cleanup.
Level2DerivedClass::Cleanup calls its parent's Cleanup implementation.
Level1DerivedClass::Cleanup calls its parent's Cleanup implementation.
What is happening is that it is calling the destructors for each level of inheritance (1 - 3) above the way I'm expecting. But when this->Cleanup() is called from the BaseClass destructor, it only executes its own implementation. I don't understand why this is happening because normally when you instantiate a derived class pointer, cast it as a base class pointer, and call a virtual method from the base class pointer (in this case, 'this'), it still runs the derived class implementation (the whole point of 'virtual', yes?). In my example, Level2DerivedClass::Cleanup and Level1DerivedClass::Cleanup never gets called.
The reason I'm setting it up this way is I want to be able to call my Cleanup code without having to destroy my object, which is why I'm abstracting it from the actual destructor body.
If you have suggestions on a more proper way to do this, I'm all ears. But I would also like an explanation of why my setup doesn't work - what am I misunderstanding?
Thank you in advance for your time.
The rule of thumb is: Never Call Virtual Functions during Construction or Destruction.
They don't behave as you might expect; as each destructor finishes, the dynamic type of this is effectively modified. From [class.cdtor] in the C++ standard:
When a virtual function is called directly or indirectly from a constructor (including the mem-initializer or
brace-or-equal-initializer for a non-static data member) or from a destructor, and the object to which the
call applies is the object under construction or destruction, the function called is the one defined in the
constructor or destructor’s own class or in one of its bases, but not a function overriding it in a class derived
from the constructor or destructor’s class, or overriding it in one of the other base classes of the most derived
object.
The Proper Way Of Doing Things is: clean after yourself, and yourself only, in the destructor. Don't clean after your kids or your parents.
If you want to clean up things not from the destructor, You Are Doing It Wrong. In C++ we have this little thing called RAII, Resource Acquisition Is Initialization. But there's also its dual, which does not seem to have an officially sounding name, but here's something that could work: RDID, Resource Disposal Is Destruction.
Of course you don't have to adhere to the RAII/RDID philosophy, but that would be Not The C++ Way.

C++ Virtual Destructors

If I have a base class and a derived class, and I delcare the destructor in the parent virtual, but instantiate an object of type subclass, when destroyed it will invoke the parent destructor right(since virtual)? If I also declare a destructor in the derived class, will it call both destructors (base and derived). Thanks in advance :-).
The second part to my question is regarding the first. Why does the base class destructor need to be declared virtual. Don't constrcutors cycle up the hiearchy. They don't share the same name, so where's the need for it? Shouldn't it work the same for destrucotrs, or by default is only one called? Also does through late binding is it able to detect all the classes and object is made of?
EDIT: My question is not just about virtual destructors, but why does it need to be declared virtual, since they should all be called by default.
Yes, parent destructors will be called automatically.
The destructor should be virtualised so a derived instance can be destroyed properly by code that thinks it has a reference to a base class instance.
In very limited circumstances, it is OK not to virtualise, if you really need to save a few cycles on the vtable lookup.
The need for virtual destructors is because of polymorphism. If you have something like the following:
class A { ... };
class B : public A { ... };
void destroy_class(A* input)
{
delete input;
}
int main()
{
B* class_ptr = new B();
destroy_class(class_ptr); //you want the right destructor called
return 0;
}
While a bit of a contrived example, when you delete the passed-in pointer for the destroy_class() function, you want the correct destructor to get called. If the destructor for class A was not declared virtual, then only the destructor for class A would get called, not the destructor for class B or any other derived type of class A.
Stuff like this is very often a fact-of-life with non-template polymorphic data-structures, etc. where a single deletion function may have to delete pointers of some base-class type that actually points to an object of a derived type.
rubixibuc,
Yeah the subclasses destructor is invoked first, then it's superclass... then it's superclass, and so on until we get to Object's destructor.
More here: http://www.devx.com/tips/Tip/13059 ... it's worth the read... only a screen-full, but it's an INFORMATIVE screen-full.