Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Revive object from destructor in C++?

Disclaimer: I know this is bad design, I am simply asking the question out of curiosity in order to try to obtain deeper knowledge of how the destructor works in C++.

In C#, one can write: GC.KeepAlive(this) in the destructor of a class (see edit below), and that would mean that the object will still be alive in memory even after the destructor call is complete.

Does the design of C++ allow reviving an object from the destructor similar to the C# algorithm described above?

Edit: As pointed out by an answer below, GC.ReRegisterForFinalize() is more closely related to the question than GC.KeepAlive(this).

like image 368
MathuSum Mut Avatar asked Feb 17 '16 13:02

MathuSum Mut


People also ask

Can a destructor return a value?

Declaring destructorsDo not return a value (or void ). Cannot be declared as const , volatile , or static . However, they can be invoked for the destruction of objects declared as const , volatile , or static .

Can a deconstructor return a value?

If you didn't author a class, struct, or interface, you can still deconstruct objects of that type by implementing one or more Deconstruct extension methods to return the values in which you're interested.

Does destructor destroy the object?

Destructors in C++ Meaning, a destructor is the last function that is going to be called before an object is destroyed. Destructor is also a special member function like constructor. Destructor destroys the class objects created by constructor.

Do destructors have a return type?

A destructor is a special member function that takes no arguments and has no return type: this is told in pretty much all the c++ books.


2 Answers

The short answer is: no. C++ does not employ garbage collection, like Java or C#. When an object is destroyed, it's destroyed immediately. Gone for good. Joined the choir invisible. Pining for the fjords, etc...

And to say this over a couple of times in different words so that there is no possible weasily reinterpretation...

The destructor is invoked as part of object destruction. Object destruction consists of invoking the destructor and deallocating the memory that was used for the object itself. It's a single process, not two separate processes. While the destructor is running, the object still exists, for the destructor to use, but it exists on borrowed time. It's a foregone conclusion that the object is going to be vaporized as soon as the destructor returns. Once a destructor is invoked, the object is going to be destroyed, and nothing is going to change its fate.

Understand this: the reason why a destructor is being invoked is because either: the object was originally allocated on the heap with "new", and it's now being "delete"d. "delete" means "delete", not "delete maybe". So the object's getting deleted. Or, if the object was allocated on the stack, the execution thread exited the scope, so all objects declared in the scope are getting destroyed. The destructor is, technically, getting invoked as a result of the object being destroyed. So, the object is being destroyed. The End.

Having said that, C++ allows you to implement a custom allocator for your classes. If you feel like it, you can write your own custom memory allocation and deallocation functions that implement whatever functionality you want. Though these are never used for stack allocated objects (i.e. local variables).

like image 186
Sam Varshavchik Avatar answered Sep 19 '22 06:09

Sam Varshavchik


You are actually misrepresenting what GC.KeepAlive does in .NET. It is not to be used in a destructor of an object to keep that object from being destructed -- actually, GC.KeepAlive() is empty and has no implementation. See the .NET source code here.

It makes sure that the object passed as a parameter is not garbage collected before the call to GC.KeepAlive happens. The object passed to KeepAlive as a parameter can be garbage collected immediately after the call to GC.KeepAlive. Since KeepAlive has no actual implementation, this happens purely based on the fact that the compiler has to maintain a reference to the object to be passed as a parameter to KeepAlive. Any other function (that is not inlined by the compiler or runtime) taking the object as a parameter could be used instead as well.

like image 31
NineBerry Avatar answered Sep 21 '22 06:09

NineBerry