Derived destructor called before base destructor causes issue - c++

Here is my issue:
My base class has a constructor that takes in a class pointer, if that pointer is NULL, it knows to instance it itself and maintain it.
The problem is, in the base destructor, I have to unregister that pointer with something private of base. So what happens is when I try to make a call to the class pointer in the base destructor and the derived is maintaining it, it has already been freed. So that causes a problem. What could I do?
Thanks

If the base class creates an instance for the pointer, why can't it free it as well? Is there anything stopping you from moving the free into the base destructor?
It's always best to be consistent in terms of who does what, at a certain level of hierarchy- splitting up the same responsibility across several levels of hierarchy will surely lead to problems such as this. Not to mention, if you want to create another class that inherits from base, you will have to re-implement this management in the new class as well, creating code duplication.

The order of constructors and destructors in inheritence is opposite; the base constructor is called before any of it's derived constructors. Upon delete, the inverse happens - the derived class is deleted first.
To solve your problem, could the base destructor not test whether its private instance is not NULL?

The base class could implement a protected member function to do the cleanup, then the derived destructor could call this helper function before destroying the resource.

From your description I gather that sometimes the derived class will be in charge of this pointer, and sometimes the base class will be. The simplest solution I can think of is to add a boolean in your base class that will allow you to track who owns the object. If the base class has initialized the pointer, set the boolean to true. Then your destructor can check who owns the object and in turn whether it should clean up.
A better solution would be to use boost:shared_ptr. This is a reference counting pointer abstraction that will automatically cleanup your object when its last reference goes out of scope. With this abstraction you generally don't need to worry about who releases your pointer.

If your constructor allocates memory, the corresponding destructor is responsible for freeing it. If you conditionally allocate memory, then you need to conditionally free it. A Boolean flag would help you determine if allocation occurred.
Another solution is to use a reference counting. At the time of the allocation the reference count shall be 1. If another class has interest in the object, it retains the pointer by increasing the reference count. If a class is no longer interested in the object, it decreases the reference count. When the counter reaches 0, the object must be deleted. shared_ptr is a standard C++ reference counted auto pointer implementation, which works very well in complex mixed ownership situations.

Related

Is accessing accessing a child attribute in the parent constructor UB when using CTRP?

I made a wandbox that captures my issue: https://wandbox.org/permlink/qAX6SL43BvERo32Z
Basically, as the tittle suggests. I am using CRTP, and my base / parent class constructor calls a child method using the standard way in CTRP.
BUT that child method uses it's own child classes's attributes, which if are of certain type, such as std::string, appear to cause runtime issues (Such as bad alloc on MSVC, and 'what(): basic_string::_M_create' / empty string on GCC).
Long story short, is this UB? If so exactly why?
Bonus points for anyone who can give suggestions for how to tackle this problem. Should / can I add an "Init" "virtual" CTRP method that the parent class calls to initialize the child variables? Should I just generally avoid CTRP calling child methods in the constructor?
Is accessing accessing a child attribute in the parent constructor UB
Yes, in general.
... when using CTRP?
And yes, in particular.
If so exactly why?
Because the behaviour of accessing an object outside its lifetime is undefined. The lifetime of the derived object and its members has not yet begun by the time the base-sub object is being constructed.
Conclusion: CRTP bases must not do the CRTP magic (i.e. you musn't do static_cast<Derived*>(this) or similar) in their constructors nor destructors (and be careful of calling member functions, as those must also not do the same).
Bonus points for anyone who can give suggestions for how to tackle this problem. Should / can I add an "Init" "virtual" CTRP method that the parent class calls to initialize the child variables?
The derived class constructor should initialize its own variables whether you use CRTP or not. The constructor should do nothing extra beyond initializing the state of the object. It shouldn't "do fruit things".

C++ Possible to make a destructor NOT call the destructor of class members and the destructor of the base class?

Is there a way to make a destructor of a class NOT call the destructor of one of the class members and/or NOT call the destructor of its base class?
In case this is not possible, is creating certain class members with placement-new and destructing (/not-destructing) them manually a possible workaround? Thanks!
EDIT:
The reason I need this: Class C owns object M. M has a non-trivial destructor. C is friend of M and manages M in a way that there is no need to call M's destructor. It is OK to call it but it means performance overhead. (it's a problem in this case.)
I was thinking to make an a derived class from M that has a destructor that does nothing, but then that would still call the destructor of the base.
At construction time, C++ ensures that the subclasses contructors are first called, then the members are contructed, and finally the appropriate constructor is applied. At destruction time the symetric is done.
That means that you cannot prevent the application of a base class destructor, nor of any member constructor, as soon as the object is destructed. If you want to only destruct some, you must find a way to not destruct the object (just use a raw pointer...) and manually call destructors on what you want. But you certainly do not want to do that!
C++ is very confident on the programmer skills, so it is easy to write a program invoking undefined behaviour. If you find yourself trying to subvert the C++ compiler to not call the destructor of a base class or of a member, you have a major problem. The member you do not want to destroy should not be a member but more probably a pointer (raw or shared) or a reference to an external object that will have its own lifetime management. And the base class should probably also be a pointer or reference to an external object, and here again the lifetime can (and should) be managed outside of the class.
If the destructor has observable side-effects, then it would be undefined behaviour to end the lifetime of the object without invoking the destructor. This is covered in C++14 [basic.life]/4:
A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.
So, there is no way to get around it. Perhaps you could redesign your code so that the destructor doesn't execute any unnecessary statements, or something.

g_object_unref() member pointer of C++ Glib::Object sub-class in destructor?

If I have C++ class derived from Glib::Object with a pointer to a g_object (C-interface) from GMime:
/* schematic set up of class */
class B : public Glib::Object {
public:
GMimeObject * mime_object;
};
the mime_object is created and then passed to class B upon instantiation. It is not g_object_unref()'ed. Should I g_object_unref() it in the destructor class B::~B()?
Yes, you need to unref it in the destructor. You may also need to call g_object_ref_sink() in the constructor to get refcounting exactly right.
GObjects which inherit from GInitiallyUnowned (rather than directly from the base GObject) start off with a "floating" reference which must be "sunk". This is the case for all GTK widgets for example. I don't know offhand whether this applies to GMimeObject or not, but the documentation will tell you (or you can call g_object_is_floating() at runtime to find out if you need to sink it).
Yes, you probably should. It would be cleanest to also create the mime_object in the constructor rather than taking a raw pointer in from outside. If you take a raw pointer from outside it may be a bit unclear who owns the object and is responsible for releasing it.
Also note that you will need to override or disable the copy constructor, else you will have a double-unref situation if B is copied.

C++: Can I use this safely in a destructor?

Todays' question is: Can I use this in a destructor, and if yes what are the restrictions I must obey to... For example, I know I'm not supposed to do anything with base classes, since they are gone. But what other restrictions apply? And can I safely assume that the this (as a pointer... ie. memory address... a number) is the same as in the constructor?
Can I use this in a destructor
Yes.
For example, I know I'm not supposed to do anything with base classes, since they are gone.
No, the base classes are still intact at this point. Members (and perhaps other base classes) of derived classes have already been destroyed, but members and base classes of this class remain until after the destructor has finished.
But what other restrictions apply?
Virtual functions are dispatched according to the class currently being destroyed, not the former most-derived class. So be careful calling them, and in particular don't call any functions that are pure virtual in this class.
Don't cast this to a derived type, since it is no longer a valid object of that type.
You can't delete this from the destructor, for obvious reasons.
And can I safely assume that the this (as a pointer... ie. memory address... a number) is the same as in the constructor?
Yes, an object's address remains the same from before its constructor runs until after its destructor runs.
As answered here it's perfectly valid.
You should avoid calling virtual functions, though.
Base classes are not gone in the destructor, you can use them normally.
Derived class are gone, so in particular virtual calls will not reach derived classes.
this has the same value as in the constructor and everywhere else in the class.
The main restriction is that you should not allow any exception to leave the destructor. This means that you have no means of indicating failure[*]. Generally you should only perform operations that are certain to succeed (such as freeing resources owned by the object): anything you do that can fail, it must be OK to ignore the failure. Anything you do that can throw, you should catch the exception. Hopefully you have fully documented the possible exceptions thrown by all the functions of this, so you know whether or not the things you want to do with this can throw.
[*] well, you could build a mechanism for the destructor to record somewhere
what happened, but users of the class would have to actively check it. This is unlikely to result in a pleasant user experience.
Since objects are destructed from the most derived class down to the base, derived classes destructors will already have executed. So you must make sure not to call methods overridden in derived classes on this. Apart from that, it's fine.
Destructor is a method, which is called before your object is physically destroyed, such that you can deinitialize it properly. In order to do so, you must have access to its fields, so you can safely access them by the this keyword.
The order of destructors is reverse to the constructors, so when your destructor runs, destructors of base classes haven't run yet - you should have access to all their fields. On the other hand, destructors of derived classes have already run, so - for example - calling virtual or abstract methods may result in undefined behavior.
Additionally, keep in mind, that it's very dangerous to throw exceptions in destructors. If you do so, you risk terminating your application.
Yes you can use it normally. You have the object there.
I don't see any problem using this in the destructor. At this time, the object is still there. The destructor is for you to free existing resources before the object is destroyed.
But avoid calling virtual functions.

Abstract class member variable

I have an abstract class, CAbstract, and want to have a member of this type in another class, CClass. If I make it a pointer, I will have to take care of the deleting myself, and do would like to avoid this.
If I make it a reference, will it get deleted automatically when the CClass gets deleted?
Can I make it a shared_ptr? Can shared_ptr manage abstract classes and pointing to derived classes?
References don't automatically deallocate anything; shared_ptr does. As long as you follow the rules of C++, it should handle inheritance situations gracefully. More specifically, since shared_ptr's destructor calls delete by default when the reference count drops to zero, you need to implement the (virtual) destructor properly to make shared_ptr work.