#counter
* スタックを使うアロケーターとshared_ptrのはなし [#q60901fc]

この記事は、[[''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を要求する邪悪なマネージャー [#f67d0382]

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;
  }
};
}}


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS