参照カウントを使用する必要shared_ptr
のない新しい標準の権利を理解していますか?このように実装されている可能性が高いというだけですか?
どういうわけか、隠されたリンクリストを使用する実装を想像することができました。N3291では「20.7.2.2.5。(8)shared_ptrオブザーバー[util.smartptr.shared.obs]」というメモに
[注:use_count()は必ずしも効率的ではありません。—エンドノート]
それは私にその考えを与えました。
参照カウントを使用する必要shared_ptr
のない新しい標準の権利を理解していますか?このように実装されている可能性が高いというだけですか?
どういうわけか、隠されたリンクリストを使用する実装を想像することができました。N3291では「20.7.2.2.5。(8)shared_ptrオブザーバー[util.smartptr.shared.obs]」というメモに
[注:use_count()は必ずしも効率的ではありません。—エンドノート]
それは私にその考えを与えました。
そうです、仕様には明示的な「カウンター」の使用を必要とするものはなく、他の可能性も存在します。
たとえば、リンクされたリストの実装は、boost の実装に提案されましたshared_ptr
。しかし、他の領域 (サイズ、コピー操作、スレッド セーフ) にコストがかかるため、提案は最終的に却下されました。
shared_ptr
「参照カウンタースマートポインター」と言う人もいます。それを見るのは正しい方法ではないと思います。
実際shared_ptr
には(非排他的な)所有権がすべてです。ポインタで初期化されたのshared_ptr
コピーであるすべて は所有者です。shared_ptr
p
shared_ptr
次のことを保証するために、一連の owner を追跡します。
delete p
ない間、呼び出されませんdelete p
のコピー) がすぐに呼び出されます。D
もちろん、所有者のセットがいつ空になるかを判断するにはshared_ptr
、カウンターのみが必要です。抽象的な記述は、考えるのが少し簡単です。
所有者の数を追跡するために、カウンターは最も明白なアプローチであるだけでなく、アトミックな比較と変更を使用してスレッドセーフにする方法も比較的明白です。
すべての所有者を追跡するために、所有者のリンクされたリストは明白な解決策であるだけでなく、所有者のセットごとにメモリを割り当てる必要を回避する簡単な方法でもあります。問題は、このようなアプローチを効率的にスレッド セーフにするのは簡単ではないことです(グローバル ロックを使用すると、何でもスレッド セーフにすることができますが、これは並列処理の概念そのものに反します)。
一方では、小さい固定サイズ (カスタム破棄関数が使用されない限り) のメモリ割り当てがあり、最適化が非常に簡単で、単純な整数アトミック操作があります。
一方、コストがかかり複雑なリンクリストの処理があります。そして、所有者ごとに設定されたミューテックスが必要な場合 (私はそうだと思います)、メモリ割り当てのコストが戻ってきます。その時点で、ミューテックスをカウンターに置き換えることができます!
「標準」クラスに対して多くの実装が可能であることを何回読んだことがありますか?
極座標として実装できる複雑なクラスという幻想を聞いたことがない人はいますか? 私たち全員が知っているように、これはばかげています。complexはデカルト座標を使用する必要があります。極座標が優先される場合は、別のクラスを作成する必要があります。通常の複雑なクラスのドロップイン置換として極性の複雑なクラスを使用する方法はありません。
(非標準の) 文字列クラスについても同様です。文字列クラスを内部的に NUL で終了し、長さを整数として格納しない理由はありません。単純に、 を繰り返し呼び出すことの面白さと非効率性のためstrlen
です。
COW を許容するように設計std::string
することは悪い考えであり、それが const イテレータの異常な無効化セマンティクスの理由であることがわかっています。
std::vector
連続性が保証されるようになりました。
ある時点で、標準クラスが多くの大幅に異なる妥当な実装を持っているという幻想は捨て去らなければなりません。標準クラスは基本的なビルディング ブロックです。非常に効率的であるだけでなく、予測可能な効率性を備えている必要があります。
プログラマーは、基本的な操作の相対速度について移植可能な仮定を作成できる必要があります。複雑なクラスは、最も単純な足し算でさえ超越的な計算の束になる場合、深刻な数の処理には役に立ちません。データ共有による文字列クラスのコピーの高速化が保証されていない場合、プログラマは文字列のコピーを最小限に抑える必要があります。
実装者は、一般的な安価な操作が(比較して)非常にコストがかからない場合にのみ、別の実装手法を自由に選択できます。
多くのクラスにとって、これは実行可能な実装戦略が 1 つだけ存在することを意味しstd::deque
ます。