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?
-
7The best way to not call a particular destructor is to not create an instance of that object to begin with. Failing that, take the code you don't want to run out of the destructor. – Ben Voigt Feb 03 '12 at 02:45
-
1I can't conceive any reason why doing this would be legitimate. And, you mentioned the only way. – David Feb 03 '12 at 02:45
-
3Too many Daves. Actually, using the heap is not the only way, but it's the simplest. – Ben Voigt Feb 03 '12 at 02:46
-
Well, not deleting the object should be more than enough to prevent an object from being destroyed... not quite sure what you are asking. Do you mean you want a static object? – whtlnv Feb 03 '12 at 02:47
-
4What problem are you trying to solve here that lead you to believe this was the best solution? – Ed S. Feb 03 '12 at 02:47
-
Are you maybe trying to solve the problem of a double delete? If so, put a breakpoint in the destructor and fix the cause of the erroneous delete. – Carl Feb 03 '12 at 02:54
-
Do you not want the object's destructor to be called or do you not want the code that's in the destructor to be run? They are two very different things. – Carl Feb 03 '12 at 02:56
-
First, let me say that my destructor has no work to do, so there's no harm in it not running. What am I trying to accomplish? I need my object to be callable (i.e. not destructed) up until the very moment my program exits. It's a static construction / destruction order problem with a lot of subtelties that I've tried to address in another thread on this forum. In this thread, I'm just trying to get ideas on how to have a destructor not run. It may not be the final solution; I'm just exploring... Besides, it's an interesting question! :) – Dave Feb 03 '12 at 03:13
-
1@Dave: Oh! If you just want it to live until the end of the program, there are a number of good ways to do that! – Ben Voigt Feb 03 '12 at 03:16
7 Answers
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.

- 1,077
- 6
- 18
-
I must have overlooked the answer from @Robin R - but anyway keeping it here. – Jarek C Nov 12 '18 at 07:58
-
Thank you, this is perfect for implementing shared_ptr/weak_ptr since we might want to destroy the underlying data inside a fat pointer independently of destroying the fat pointer itself. – AMACB Oct 10 '21 at 23:17
Not recommended, but here's another way:
char buffer[sizeof(T) + alignof(T)];
char* aligned_buffer = buffer + alignof(T) - reinterpret_cast<intptr_t>(buffer) % alignof(T);
T* object = new (aligned_buffer) T;
However, although this means the compiler won't automatically call the destructor, the programmer still can:
object->~T();
Of course, that's also true with heap allocation:
delete object;
To prevent that, you'll have to make the destructor inaccessible:
struct T
{
private:
~T() {};
};
Or really inaccessible (related: Why must a base class destructor be accessible only when a custom constructor is declared?):
class indestructible_base
{
~indestructible_base();
};
struct T : indestructible_base
{
};
-
@Loki: A vector doesn't answer "Is there any way to do this other than putting the object on the heap?", since the vector's content is right back on the heap. – Ben Voigt Feb 03 '12 at 02:56
-
3OMG, someone wrote this static buffer hack *and aligned the object properly*. I can't believe this happened. +1. – R. Martinho Fernandes Feb 03 '12 at 02:59
-
1
-
@Loki: Anyway, I see no guarantee that vector content is suitably aligned for any type other than the element type. – Ben Voigt Feb 03 '12 at 03:53
-
@Loki: I'm familiar with that requirement. But I don't see how it applies to `std::vector` data. – Ben Voigt Feb 03 '12 at 04:06
-
"the storage is obtained by calling `::operator new(std::size_t) (18.6.1)`, but it is unspecified when or how often this function is called"... the allocator is allowed to pool memory, alignment is only assured suitable for the allocator's element type. – Ben Voigt Feb 03 '12 at 04:18
-
OK got it. You are correct. The important part (that I previously missed) being: `20.6.9.1 allocator members [allocator.members] paragraph 5` – Martin York Feb 03 '12 at 04:57
Following how std::optional operates, you can create your own simpler object wrapper template:
#include <iostream>
template <typename T_>
struct Wrapper
{
union {
char dummy_;
T_ value_;
};
bool shouldDestroy_ {true};
template<typename ...Args>
Wrapper(Args &&... args) :
value_(std::forward<Args>(args)...)
{
}
const T_ &value() const { return value_; }
T_ &value() { return value_; }
const T_ *get() const { return &value_; }
T_ *get() { return &value_; }
const T_ *operator->() const { return get(); }
T_ *operator->() { return get(); }
void destroy(bool destroy) { shouldDestroy_ = destroy; }
~Wrapper()
{
if (shouldDestroy_) {
value_.~T_();
}
}
};
int main()
{
struct Foo
{
Foo() { std::cout << "Foo()\n"; }
Foo(int value) { std::cout << "Foo(" << value << ")\n"; }
~Foo() { std::cout << "~Foo()\n"; }
void display(const char *str) { std::cout << str << "\n"; }
};
std::cout << "Running...\n";
// example 1 construct/destructed
{
Wrapper<Foo> a;
a.value().display("via value 1");
a->display("via operator 1");
}
// example 2 construct/destructed
{
Wrapper<Foo> a(2);
a.value().display("via value 2");
a->display("via operator 2");
}
// example 3 construct NOT destructed
{
Wrapper<Foo> a(3);
a.value().display("via value 3");
a->display("via operator 3");
// do not allow destroy
a.destroy(false);
}
return 0;
}
And the output will be as follows:
Running...
Foo()
via value 1
via operator 1
~Foo()
Foo(2)
via value 2
via operator 2
~Foo()
Foo(3)
via value 3
via operator 3

- 1,037
- 10
- 6
If you want an error to occur upon calling the destructor then simply don't provide a definition for it:
struct foo {
~foo();
};
Or delete
it in C++11:
struct foo {
~foo() = delete;
};
If you only want it to be called sometimes then you almost certainly need to rethink your design. There's no "safe" way to do it, and while using new
without delete may work, I strongly suggest you don't.
Alternatively you could add a flag if you sometimes want certain destructor behavior:
struct foo {
foo(bool destroy = true) : destroy(destroy) {}
~foo() {
if(destroy) {
// destruction stuff here
}
}
bool destroy;
};

- 51,882
- 13
- 139
- 180
-
For your first 2 examples, `foo` still needs to be on the heap if you want to use `foo`. – Jesse Good Feb 03 '12 at 02:58
-
@Jesse: See my answer for a way to instantiate such a class without using the heap. But then DON'T DO IT! – Ben Voigt Feb 03 '12 at 03:04
You can call new operator with preallocated memory and give pointer to local variable which is on stack so it will be living on stack allocated area:
void myfunc() {
char stackMemoryForMyClass[sizeof(Type)];
Type* t = new (stackMemoryForMyClass) Type;
// destructor will not be called
}

- 2,078
- 1
- 17
- 23
I know this is 10 years old, but I needed to stop a destructor from executing recently (destructor unloaded a manually mapped bit of data from the binary, I needed that manually mapped bit of data to be persistent until the executable itself completed running for one instance of an object instantiated all over)
Easiest way was to add a public bool to the object and wrap the destructor in that bool. Strictly speaking does not 'prevent the destructor from running', but it does control the flow of the destructor which you do not typically see.
Class::~Class()
{
if (bPersisent)
{
Disable();
}
}

- 3
- 2