9

私のプロジェクトでは、いくつかの STL コンテナーをゼロから作成しています (理由があります)。私はSTLの機能とインターフェースを非常に厳密に模倣しているので、「標準構造と同じ名前であれば、可能な限り標準に準拠する」というポリシーを守るために最善を尽くしています。

もちろん、私のコンテナはテンプレート パラメータとしてアロケータを使用します。これは、いくつかのカスタム割り当てスキームを可能にするので非常に便利です。私の質問に進みます。

このstd::allocatorインターフェイスは、メモリの割り当てをオブジェクトの構築から分離します。同様に、解放と破壊を分離します。どこからメモリを取得するかは、c++ でオブジェクトを適切に構築することと多かれ少なかれ無関係であるため、これは理にかなっています。

したがって、デフォルトの実装では次のような 2 つの構築/割り当て解除関数があります (本から直接引用)。

void construct(pointer p, const T& val)    { new(p) T(val); }
void destroy(pointer p)                    { p->~T(); }

ご覧のとおり、construct は単にplacement new を呼び出し、destroy は単にデストラクタを呼び出します。

配置の新しい構文とデストラクタ構文を使用するだけでなく、これらを使用する理由はありますか? 「正しい」アロケーターはこれらを別の方法で実装できますか? または、標準に準拠するすべてのアロケータ実装に、この方法で実装されたメソッドの構築/破棄があることが保証されていますか?

もっと言えば、コンテナーの要素を構築するためにいつでもstd::uninitialized_copyandを使用できると言っても過言ではありませんか?std::uninitialized_fill

ありがとう。

4

2 に答える 2

11

アロケータは、構築/破棄の前後にログ ステートメントを追加したり、必要なその他の副作用を追加したりできます。

もちろん、実際の構築は、placement new とデストラクタを呼び出すことによって発生する必要がありますが、ルールブックには、構築/破棄関数で他に何も起こらなければならないとは書かれていません。

于 2009-03-17T01:28:18.713 に答える
3

これは、メソッド内の割り当ての詳細を非表示にするためです。つまり、構築と破棄のための API を提供していますが、将来的には実装を変更できます。現在、placement new を使用してメモリを割り当てています。将来、割り当てを変更したい場合は、これら 2 つのメソッドを変更するだけです。

于 2009-03-17T01:20:02.743 に答える