この記事は、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;
}
};