-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add virtual destructor to thread.h to prevent undefined behavior on destruction. #25
base: master
Are you sure you want to change the base?
Conversation
I would say you are right, if it was a common case. Typically virtual destructor must be defined in case of polymorphic classes. But there can be the dragons. But I agree, to make library bulletproof it would be nice to have virtual destructor for thread to avoid any misuse or errors in custom-defined derived classes. |
Will this add incompatibility of any kind? If I understand correctly, the purpose of this is to allow inherited classes (other than the core itself) to know when it got destcructed. |
Once again with the disclaimer that I'm a Java guy... but I don't think it will. My understanding is that it will only call a destructor if it exists. If no destructor exists nothing will happen. If a destructor does exists it will now be called when you destroy pointer to base class, not only when you destroy the pointer to the derived class. This is a changed behavior but I really can't see a case where you really would like to call the destructor for the derived class only but not when destroing via a base class. |
I'll clarify the things a little bit.
There is always a destructor. At least default one (generated automatically if no specific destructor defined in the class), it may appear it does nothing, but at least it calls all the desructors from all the class members. Destructor can be normal or virtual, the main difference between them - if you destroy a class without virtual destructor, the destructor of that class will be called (if you destroy a pointer to base class - only base class destructor will be called disregard to the fact that the pointer may point do some derived class). That is absolutely the same behavior if you call non-virtual function. The drawback of non-virtual destructors - potential memory or resources leak. If you have a pointer to base class, but create derived class which allocates some additional resources for itself, only the base class destructor will be called and all the resources allocated in derived class will leak. Virtual destructors solve that problem. This change won't introduce any incompatibility unless somebody use precompiled version of this library (which is very very unlikely). The same problem with compatibility with precompiled libraries may happen if you just introduce any new method. There are no problems with compatibility if the project have always built from the sources. |
According to the documentation of ArduinoThread one should be able to inherit from the Thread class:
"Inheriting from Thread or even ThreadController is always a good idea. For example, I always create base classes of sensors that extends Thread, so that I can "register" the sensors inside a ThreadController, and forget about really reading sensors, just getting theirs values within my main code. Checkout SensorThread example."
When doing this in Eclipse I get an error like "Class 'XXX' has virtual method 'run' but non-virtual destructor"
according to this:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#discussion-make-base-class-destructors-public-and-virtual-or-protected-and-nonvirtual
a base class should define a public virtual destructor otherwise destruction via a pointer to a base class would lead to undefined behavior (and a possible memory leak as the inherited destructor isn't guaranteed to be called).
...and a disclaimer: I'm originally a Java guy and has just recently started to learn C++. I might have gotten everything completely wrong :)