#counter * スタックを使うアロケーターとshared_ptrのはなし [#wf412eb9] この記事は、[[''C++ Advent Calendar 2013''>http://partake.in/events/91328710-3c7b-436e-bd4e-4d98d88333f9]] 6日目の記事です。 -Prev 5日目の記事 [[hotwatermorning>http://hoge.hoge]] -Next 7日目の記事 [[srz_zumix>http://hoge.hoge]] * shared_ptrを要求する邪悪なマネージャー [#a0ddeea8] C++11で標準実装された、参照カウンタ方式によるポインタ'shared_ptr'。 古来のC++でもboostライブラリにより利用かのなので、すっかりおなじみのスマートポインターです。 なにせ、newしてもdeleteしなくて良いというお手軽さ。誰からも参照されなくなると勝手にdeleteされるという、慎ましやかな動作で人気を博しています。 初期のboostライブラリから実装されていたこともあり、shared_ptrを使ったクラスライブラリも多いのですが、中にはイケてないクラスもあります。なにがイケてないかというと、 - shared_ptrをコンテナに入れて保持している - シングルトン実装で、コンテナの解放はアプリケーション終了時である - 格納されるクラスが、ポインタや参照で他のクラスオブジェクトと依存関係にある これらの要件を満たしているクラスを使うと、便利でお手軽なshared_ptrはバグの温床と化し、未定義動作の暗黒面へと落ちて行きます。 くわしくは[[こちら>EvilTaskManager]] #sh(cpp){{ // イケてないタスクマネージャー 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; } }; }}