C++ スマートポインタの実装
C++のスマートポインタは、動的に割り当てられたオブジェクトを扱うためのポインタで、メモリを自動的に解放する仕組みを提供し、メモリリークやぶら下がりポインタなどの問題を防ぐことができます。
C++11以降の標準ライブラリには、std::shared_ptrとstd::unique_ptrの2種類のスマートポインタが用意されています。それぞれの実装方法について以下に説明します。
- 擬似参照カウントを使用したスマートポインタで、複数のポインタから1つのオブジェクトを共有、管理できます。参照カウントがゼロになるとオブジェクトは自動で解放されます。
std::shared_ptrの実装方法は、以下のとおりです。
- テンプレートクラス shared_ptr を定義し、オブジェクトへのポインタと参照カウントへのポインタを含めます。
- コンストラクタでダイナミックメモリ確保したオブジェクトを作成し、参照カウントを1で初期化する。
- コピーコンストラクタで参照カウンタをインクリメントする
- デストラクタで参照カウンタを1減らし、参照カウンタが0のときオブジェクトを解放します。
- shared_ptr をネイティブポインタのように使用できるように上書き矢印演算子と逆参照演算子を上書きします。
- std::unique_ptr はオブジェクトを一つだけ指す、排他的所有権を持つスマートポインタで、ポインタが破棄されると自動的に管理しているオブジェクトも解放されます。
std::unique_ptrの実装は次の手順で作成できます。
- 指向オブジェクトのポインタを含むクラステンプレート unique_ptr を定義します。
- コンストラクタ内で動的オブジェクトを作成する。
- ユニークポインタのムーブセマンティクスをサポートするためにムーブコンストラクタとムーブ代入演算子を実装する。
- デストラクタで、オブジェクトを解放します。
上で述べたものはスマートポインタの基本的な実装の考え方に過ぎず、実際には標準ライブラリのスマートポインタはより多くの詳細や例外の安全性などを考慮しています。実際の使用では、自分で実装するのではなく、標準ライブラリが提供するスマートポインタを使用することを推奨します。