STL の勉強をするために Visual Studio 2015 の std::map をコードレーディングした時のメモ。
_Tree
にアルゴリズムの実装がある。(ヘッダーファイル xtree)- アルゴリズムは赤黒木。
_Tmap_traits
がキーを使って比較するための関数オブジェクト。_Tmap_traits
を噛ませることで実際の木の実装と,内部オブジェクトの分離を図っている。- 高速化やデバッグコードの分離のために複数のイテレーターが存在する模様。
STL の勉強をするために Visual Studio 2015 の std::map をコードレーディングした時のメモ。
_Tree
にアルゴリズムの実装がある。(ヘッダーファイル xtree)_Tmap_traits
がキーを使って比較するための関数オブジェクト。_Tmap_traits
を噛ませることで実際の木の実装と,内部オブジェクトの分離を図っている。make_shared で確保されたメモリ領域は,それを参照する weak_ptr が無くならない限り解放されない
がイマイチしっくり来なかったので、自分でコード作る+make_shared
のコードを追いかけて理解したので、
それのメモ。
以下のようなコードをメモリ使用量を監視しながらステップ実行して確かにそのようなことを起こっていることを確認出来た。
というわけで、どうしてそうなっているのかをソース追いかけてみる。 そうすると内部で、
_Ref_count_obj<_Ty> *_Rx =
new _Ref_count_obj<_Ty>(_STD forward<_Types>(_Args)...);
と内部オブジェクトを作っているようだが、事実上これが shared_ptr
の中身だと思って良さそうだ。
で、実際にそのコンストラクタのコードがこんな感じ。
template<class... _Types>
_Ref_count_obj(_Types&&... _Args)
: _Ref_count_base()
{ // construct from argument list
::new ((void *)&_Storage) _Ty(_STD forward<_Types>(_Args)...);
}
つまり、placement new を使って _Ref_count_obj
の中に、そのままオブジェクトを構築していることになる。
この _Ref_count_obj
は _Ref_count_base
を継承しているが、これが参照カウンタを持っている。
管理用のカウンタとオブジェクト本体が一緒になっているので、
オブジェクトを参照している weak_ptr
と shared_ptr
がなくならなければオブジェクトが開放されないというのも納得である。
make_shared
の中ではメモリの確保回数を減らすためにこのような処理を行っている、ということがわかっていればそれほど難しい事ではなかった。
で定義されるフーリエ変換の結果を纏めておく。