Saltar a contenido

Última actualización:2026-10-12

Comparación de destructores entre C++ y Rust

En Rust, mem::forget se usa para impedir la destrucción de un objeto, saltándose la limpieza, de modo que la liberación de los recursos queda a cargo de otro mecanismo.

Por ejemplo:

let file = File::open("foo.txt").unwrap();
mem::forget(file);
¿Y en C++ cómo impedir la destrucción, es decir, saltarse el destructor?

Esta sección presenta tres formas de hacerlo; los ejemplos de código completos también están en el planeta de conocimiento.

1. placement new

placement new nos permite gestionar manualmente la construcción y la destrucción del objeto. Si no llamamos manualmente al destructor del objeto, podemos saltarnos su destrucción y lograr un efecto similar al de mem::forget.

Por ejemplo:

alignas(Foo) std::byte storage[sizeof(Foo)];  // 分配对齐的原始内存块
Foo* pfoo = new (storage) Foo();  // 在这块内存上构造Foo对象
En el código anterior, placement new crea el objeto pfoo, pero como no llamamos al destructor, se salta la lógica de limpieza del objeto.

2. Usar un eliminador personalizado con punteros inteligentes

Otra forma de conseguir una función similar es personalizar el eliminador (deleter) del puntero inteligente para impedir que el objeto se destruya. Podemos definir un eliminador que no haga nada, evitando así la llamada al destructor.

std::unique_ptr<Foo, NoOpDeleter> pfoo(new Foo(), NoOpDeleter{});
Con el eliminador personalizado NoOpDeleter podemos impedir que std::unique_ptr invoque el destructor al salir del ámbito, logrando un efecto similar al de mem::forget.

3. union

La solución con union es asombrosa: ¿conocéis el principio? Os invito a comentarlo en la zona de mensajes~

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

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

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

Temas relacionados

Comentarios