1. 導入
C++で動的にメモリを確保する際、手動でdeleteを行うとメモリリークの危険が伴います。そこで登場するのがスマートポインタですが、単にstd::shared_ptrをnewで生成するだけでは不十分な場合があります。本記事では、メモリ効率と安全性、そしてコードの簡潔さを両立させるstd::make_sharedの重要性について解説します。
2. 基礎知識
std::shared_ptrは、参照カウンタを用いて、オブジェクトを指す所有者がいなくなった瞬間に自動的にメモリを解放するスマートポインタです。
通常、std::shared_ptr
3. 実装/解決策
std::make_sharedを使用することで、new演算子を直接記述する必要がなくなります。これにより、例外安全性が向上します。例えば、関数の引数として複数のnewが渡される場合、ある箇所で例外が発生するとメモリリークが起きるリスクがありますが、make_sharedを使えばその懸念を解消できます。
4. サンプルプログラム
以下は、std::make_sharedを使用してクラスを生成する実用的なコードです。
#include
include
include
class User {
public:
User(std::string name) : name_(name) {
std::cout << name_ << " が作成されました。" << std::endl;
}
~User() {
std::cout << name_ << " が破棄されました。" << std::endl;
}
void SayHello() { std::cout << "こんにちは、" << name_ << "です。" << std::endl; }
private:
std::string name_;
};
int main() {
// std::make_sharedを使用してオブジェクトを生成
// コンストラクタの引数はmake_sharedの引数として渡します
auto user = std::make_shared
user->SayHello();
// 参照が切れると自動的にメモリが解放されます
return 0;
}
5. 応用・注意点
std::make_sharedには1点だけ注意すべきケースがあります。それは、オブジェクトのサイズが非常に大きく、かつstd::weak_ptrによって参照が保持され続ける期間が長い場合です。
std::make_sharedは「オブジェクト」と「制御ブロック」を一つのメモリ領域に確保するため、オブジェクトへの参照がなくなっても、weak_ptrが残っている限りメモリ全体が解放されません。この特殊なケース以外では、基本的にstd::make_sharedを積極的に使用するのが現代のC++開発におけるベストプラクティスです。

コメント