この記事は、C++ Advent Calendar 2013 6日目の記事です。
C++11で標準実装された、参照カウンタ方式によるポインタ'shared_ptr'。 古来のC++でもboostライブラリにより利用かのなので、すっかりおなじみのスマートポインターです。
なにせ、newしてもdeleteしなくて良いというお手軽さ。誰からも参照されなくなると勝手にdeleteされるという、慎ましやかな動作で人気を博しています。
初期のboostライブラリから実装されていたこともあり、shared_ptrを使ったクラスライブラリも多いのですが、中にはイケてないクラスもあります。なにがイケてないかというと、
これらの要件を満たしているクラスを使うと、便利でお手軽なshared_ptrはバグの温床と化し、未定義動作の暗黒面へと落ちて行きます。
くわしくはshared_ptrを要求する邪悪なマネージャーの顛末
// イケてないタスクマネージャー struct EvilTaskManager { // 管理されるタスククラスのインターフェイスクラス struct Task { virtual void update() = 0; }; // タスクリストをshared_ptrを使って保持 vector<shared_ptr<Task>> tasks_; // タスクリストにタスクを追加 void addTask(shared_ptr<Task> task) { tasks_.push_back(task); } // タスクリストのすべてのタスクのupdate()を呼び出す。 void doUpdate() { for (auto& task : tasks_) task->update(); } // タスクリストをクリア void clear() { tasks_.clear(); } // シングルトン実装です static EvilTaskManager& instance() { static EvilTaskManager me; return me; } };