最終更新:2026-10-12
C++ と Rust のデストラクタ比較¶
Rustではmem::forgetはオブジェクトのデストラクタを防ぎ、クリーンアップ作業をスキップして、リソースの解放を他の仕組みに任せるために使われます。
例えば:
ではC++ではどうやってデストラクタを防ぐのでしょうか?すなわち、デストラクタをスキップするには?
本節では3つの方法を示します。完全なコード例も星球に掲載しています。
1. placement new¶
placement newを使うと、オブジェクトの構築と破棄を手動で管理できます。オブジェクトのデストラクタを手動で呼び出さなければ、オブジェクトのデストラクタをスキップでき、mem::forgetと同様の効果を実現できます。
例えば:
alignas(Foo) std::byte storage[sizeof(Foo)]; // 分配对齐的原始内存块
Foo* pfoo = new (storage) Foo(); // 在这块内存上构造Foo对象
上のコードでは、placement newがオブジェクトpfooを生成していますが、デストラクタを呼ばないことで、オブジェクトのクリーンアップ処理をスキップできます。
2. スマートポインタのカスタムデリータを使う¶
同様の機能を実現するもうひとつの方法は、スマートポインタのデリータをカスタマイズして、オブジェクトが破棄されるのを防ぐことです。何もしないデリータを定義することで、デストラクタの呼び出しを避けられます。
カスタムデリータNoOpDeleterを使うことで、std::unique_ptrがスコープを抜けるときにデストラクタを呼び出すのを防ぎ、mem::forgetと同様の効果を実現できます。
3.union¶
unionの方法はなかなか不思議です。原理を皆さんはご存じでしょうか?コメント欄で一緒に議論しましょう~
template <class T>
union Wrapper {
T value;
~Wrapper() {}
};
struct Foo {
~Foo() { std::cout << "dtor foo\n"; }
};
Wrapper<Foo> f;
// f.value.~Foo); 必须手动调用
関連トピック¶
- C++ 純粋仮想関数と抽象クラス | C++那些事
- C++ assert アサーション | C++那些事
- C++ ビットフィールド | C++那些事
- C 言語による C++ 多態の実現 | C++那些事
- C++ const 定数と修飾 | C++那些事
- C++ const ファミリー | C++那些事
- C++ 間接参照演算子 * | C++那些事
- C++ 初期化と代入 | C++那些事
- C++ 複数戻り値の書き方 | C++那些事
- C++ mutable キーワード | C++那些事