Skip to content

Last updated:2026-10-12

C++ vs Rust Destructor Comparison

In Rust, mem::forget is used to prevent an object's destructor from running, skipping the cleanup work so that the release of resources is left to other mechanisms to manage.

For example:

let file = File::open("foo.txt").unwrap();
mem::forget(file);

So how do you prevent destruction in C++ — that is, skip the destructor?

This section gives three ways to do it; the complete code examples are also in the Knowledge Planet.

1. placement new

placement new lets us manually manage an object's construction and destruction. If we do not manually call the object's destructor, we can skip the object's destruction, achieving an effect similar to mem::forget.

For example:

alignas(Foo) std::byte storage[sizeof(Foo)];  // 分配对齐的原始内存块
Foo* pfoo = new (storage) Foo();  // 在这块内存上构造Foo对象

In the code above, placement new creates the object pfoo, but we do not call the destructor, thereby skipping the object's cleanup logic.

2. Using a Custom Deleter for Smart Pointers

Another way to achieve similar functionality is to customize the deleter of a smart pointer to prevent the object from being destroyed. We can define a deleter that does nothing, thereby avoiding the call to the destructor.

std::unique_ptr<Foo, NoOpDeleter> pfoo(new Foo(), NoOpDeleter{});

Using the custom deleter NoOpDeleter, we can prevent std::unique_ptr from calling the destructor when it leaves scope, achieving an effect similar to mem::forget.

3. union

The union approach is quite magical — do you know how it works? Feel free to discuss it in the comments~

template <class T>
union Wrapper {
  T value;
  ~Wrapper() {}
};

struct Foo {
  ~Foo() { std::cout << "dtor foo\n"; }
};

Wrapper<Foo> f; 
// f.value.~Foo);  必须手动调用

Comments