Ir para o conteúdo

Última atualização:2026-10-12

Comparação de destrutores: C++ vs Rust

Em Rust, mem::forget é usado para impedir a destruição do objeto, pulando a limpeza e deixando a liberação dos recursos a cargo de outros mecanismos.

Por exemplo:

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

E em C++, como impedir a destruição, ou seja, pular o destrutor?

Esta seção apresenta três métodos; os exemplos de código completos também estão no Planeta do Conhecimento.

1. placement new

O placement new nos permite gerenciar manualmente a construção e a destruição do objeto. Se não chamarmos manualmente o destrutor do objeto, podemos pular a sua destruição, obtendo um efeito semelhante ao de mem::forget.

Por exemplo:

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

No código acima, o placement new cria o objeto pfoo, mas, como não chamamos o destrutor, a lógica de limpeza do objeto é pulada.

2. Usar um deleter personalizado com ponteiros inteligentes

Outra forma de obter funcionalidade semelhante é personalizar o deleter do ponteiro inteligente, impedindo que o objeto seja destruído. Podemos definir um deleter que não faz nada, evitando assim a chamada do destrutor.

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

Com o deleter personalizado NoOpDeleter, podemos impedir que o std::unique_ptr chame o destrutor ao sair de escopo, obtendo um efeito semelhante ao de mem::forget.

3.union

A solução com union é surpreendente — você sabe como ela funciona? Deixe um comentário para discutirmos juntos~

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

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

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

Tópicos relacionados

Comentários