I would like to ensure that an object's destructor does not run. Is there any way to do this other than putting the object on the heap and not calling delete?
I'm surprised that nobody mentioned completely C++ standard compliant solution with union
. In union
no constructor even destructor is called automatically for members. Even in case there is only one member in the union. All that must be done "manually":
constructor can be called through so called "placement new" (or from a constructor init list introduced by :
),
destructor can be called by explicit call of destructor method.
Demo:
class MyObj {
int i;
public:
MyObj(int i_) : i(i_) { std::cout << i << " constructed" << std::endl; }
MyObj(MyObj const &src) : i(src.i + 100) { std::cout << src.i << " copied to new " << i << std::endl; }
~MyObj() { std::cout << i << " destroyed" << std::endl; }
};
class OptDestr {
bool callDestructor;
union { MyObj o; }; // Only allocated, but no constr/destr is called automatically
public:
// Constructor
OptDestr(int i, bool callDestructor_) : callDestructor(callDestructor_),
o(i) // calls MyObj constructor
{ }
// OR alternatively:
OptDestr(int i, bool callDestructor_) : callDestructor(callDestructor_) {
new (&o)MyObj(i); // placement new - does NOT allocate, just calls constructor
}
// Copy constructor
OptDestr(OptDestr const &src) : callDestructor(src.callDestructor),
o(src.o) // explicit call of MyObj copy-constructor
{ }
// OR alternatively:
OptDestr(OptDestr const &src) : callDestructor(src.callDestructor) {
new (&o)MyObj(src.o); // placement new - no allocation, just explicitly calls copy-constructor of MyObj
}
// Destructor
~OptDestr() {
if (callDestructor) o.~MyObj(); // explicit call of destructor
}
};
int main() {
OptDestr d1(1, false /*callDestructor*/);
OptDestr d1_copy(d1);
OptDestr d2(2, true /*callDestructor*/);
OptDestr d2_copy(d2);
}
The output of the program is the following:
1 constructed
1 copied to new 101
2 constructed
2 copied to new 102
102 destroyed
2 destroyed
You can see that there is no 1 destructed
neither 101 destructed
. I would guess that types like std::Optional
are implemented in a similar way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With