| | 244 | |
| | 245 | |
| | 246 | == Boost.Flyweight == |
| | 247 | |
| | 248 | * Flyweight パターンを実装 |
| | 249 | * 等価なインスタンスを別々の箇所で使用する際、1つのインスタンスを再利用することによって省リソース化。 |
| | 250 | |
| | 251 | === 導入 === |
| | 252 | |
| | 253 | * '''const''' の難点 |
| | 254 | * 「変更しない」と「変更されない」は割と別物だが、 C++ の const はそれらを一緒くたに扱っている。 |
| | 255 | * そこで immutable |
| | 256 | * 値を共有できる |
| | 257 | * その為には GC が欲しい… |
| | 258 | * std::shared_ptr<T const> で実装する |
| | 259 | * Flyweight デザインパターンは「値の共有」という考え方を突き詰めたもの。 |
| | 260 | * 基本的には shared_ptr<T const> と変わらん。 |
| | 261 | * 等値のオブジェクトを1つの値にまとめ上げる点だけ異なる。 |
| | 262 | |
| | 263 | === 利点 === |
| | 264 | |
| | 265 | * 気軽に使える |
| | 266 | * 非侵入的 |
| | 267 | * const T が要件を満たせばどんな型でも Flyweight にできるよ |
| | 268 | * T const& への暗黙変換 |
| | 269 | * 細かく条件を設定できる |
| | 270 | * オブジェクトを保持するデータ構造、 GC の方法、 key-value flyweight による遅延構築、etc... |
| | 271 | * パフォーマンス |
| | 272 | * 公式ページ参照 |
| | 273 | * std::string のようなクラスの場合 |
| | 274 | * 構築は遅い |
| | 275 | * コピーや等値比較は非常に高速 |
| | 276 | * ハッシュ関数として保持されたオブジェクトのアドレスを利用可能。 |
| | 277 | * 特に unordered な連想コンテナに格納する場合に非常に強力!! |
| | 278 | |
| | 279 | === ぼくのかんがえたさいきょうのもじれつクラス === |
| | 280 | |
| | 281 | {{{ |
| | 282 | #!cpp |
| | 283 | typedef boost::flyweight<std::string> fstring; |
| | 284 | }}} |
| | 285 | |
| | 286 | === 問題点 === |
| | 287 | |
| | 288 | * ハッシュ関数はどうしよう? |
| | 289 | * アドレスを使うのは楽だが、プログラムを実行する度に値が変わる |
| | 290 | * 空間効率を落として良いなら、 flyweight に格納する文字列にハッシュ値を紛れ込ませられる |
| | 291 | * 実装がかなり面倒くさい |
| | 292 | * std::string ってメンバ関数が多い |
| | 293 | * どこまで? |
| | 294 | * Boost.Flyweight を使わずに |
| | 295 | |
| | 296 | === より実際的な例 === |
| | 297 | |
| | 298 | * Key-Value Flyweight を使った例 |
| | 299 | {{{ |
| | 300 | #!cpp |
| | 301 | boost::flyweight<boost::flyweight::flyweights<Key, Value> > |
| | 302 | }}} |
| | 303 | * 構築時は key, 使用時は value として扱える |
| | 304 | * Value の生成は遅延される |
| | 305 | * Lua ネタ |
| | 306 | * Lua のソースファイルを扱うクラス |
| | 307 | * コンパイル済みのチャンクを保存し対象ファイルが更新されない限り次からはそちらを使うことで高速化 |
| | 308 | |
| | 309 | === まとめ === |
| | 310 | |
| | 311 | * 便利だよ! |
| | 312 | |