C++ 2003では、アロケータモデルが壊れていて、本当に適切な解決策はありません。 C++ 2011の場合、アロケータモデルは固定されています。インスタンスアロケータは、含まれているオブジェクトに伝播することができます(ただし、それらを置き換えることを選択しない限り)。一般的には、これを有効にするには、デフォルトのstd::allocator<T>
が必須ではない動的多型アロケータ型を使用したいと思うかもしれません(そして、これはより良い実装の選択肢かもしれませんが、一般的には動的多型ではないと思います)。しかし、メモリ割り当てを行う標準C++ライブラリのすべてのクラスは、テンプレート引数としてアロケータ型を取るテンプレートです(例えば、IOStreamsは例外ですが、一般的に、アロケータサポートの追加を保証するために興味深い量のメモリを割り当てません) )。
あなたのコメントの中には、アロケータが効果的にグローバルになる必要があることが主張されています。これは間違いなく間違いです。各アロケータ対応型は与えられたアロケータのコピーを格納します(少なくとも、インスタンスレベルのデータを持っている場合は、operator new()
とoperator delete()
を使用するデフォルトのアロケータの場合のように何も格納されていない場合) 。これは、事実上、アロケータを使用するアロケータが存在する限り、オブジェクトに割り当てられたアロケーションメカニズムが固執する必要があることを意味します。このはをグローバルオブジェクトを使用して行うことができますが、グローバルオブジェクトを使用して行うこともできます。アロケータをそれが与えられた全てのオブジェクトを含むオブジェクトに関連付けることを含む。たとえば、XML、Excel、Pagesなどあらゆる構造ファイルがメンバーにアロケータを渡すと考えると、アロケータはそのドキュメントのメンバーとして生きることができ、すべてのコンテンツが破棄された後にドキュメントが破棄されると破棄されます。アロケータモデルのこの部分は、アロケータ引数を取る限り、pre-C++ 2011クラスでも動作するはずです。ただし、C++ 2011以前のクラスでは、アロケータは含まれたオブジェクトに渡されません。たとえば、アロケータにstd::vector<std::string>
を指定すると、に割り当てられたアロケータを使用してstd::string
に適切に変換されたC++ 2011バージョンでは、std::string
が作成されます。これは、C++ 2011以前のアロケータでは発生しません。
サブシステムで実際にアロケータを使用するには、関数やクラスへの引数として明示的に渡すか、コンテキストとして機能するアロケータ対応オブジェクトによって暗黙的に渡す必要があります。たとえば、標準コンテナのいずれかをコンテキストの一部として使用する場合は、get_allocator()
メソッドを使用して使用済みアロケータを取得できます。
なぜアロケータはグローバルでなければならないのですか?割り当てられた各ユニットが独自のアロケータへの参照を持ち、正しく解放できる場合、アロケータが実際にどこにあるかは重要ですか? –
アロケータは、割り当てられたユニットのどこに残しますか?あたかもそれがグローバルでなければならないかのように思えます。 – chadb