3

オブジェクトをどのようにstd::vector割り当てますか?まるでstd::allocator::allocateメモリのブロックを作成するために使用しているように見えますが、それからを呼び出すことはありませんstd::allocate::construct。これは本当ですか?std::vectorメモリを割り当てるだけで、メモリ割り当てとしてオブジェクトを構築することはありませんか?

デフォルトのコンストラクターがない場合はどうなりますか?オブジェクトにデフォルトのコンストラクターがない場合、コンストラクターはどのように呼び出されますか?複数のパラメーターがある場合はどうなりますか?

たとえば、このコードにはデフォルトのコンストラクターはなく、std::allocatorで許可されています。

#include <vector>
using namespace std;

class A{
protected:
    int m;
public:
    explicit A(int a) : m(a) { }
};

int main(){
    vector<A> test;
    return 0;
}
4

2 に答える 2

8

これはC++11以降かなり変更されています。

C ++ 03ではconstruct、インプレースでのみコピー構築を実行できました。

ただし、std::vector特にオブジェクトの配列ですが、サイズと容量が異なることに注意してください。つまり、有用なデータを含む配列の部分の終わりを超えて、より多くの空の要素が存在する可能性があります。

そのため、標準ライブラリのアロケータでは、「構築」と「メモリ割り当て」が分離されています。はallocator両方を実行しますが、同時には実行しません。これにより、使用std::vectorするよりも多くのメモリを割り当てることができます。新しい要素を追加する場合、必ずしもより多くのメモリを割り当てる必要はありません。への呼び出しを介して、残っているスペアメモリを使用することができますallocator::construct

std::vector また、要素をパラメーターとして受け取るために要素を追加するすべてのC++03関数に注意してください。push_back、、サイズ変更されたコンストラクターinsertでさえ、引数として値を取ります。はい、これはデフォルトのパラメータですが、それでも要素として値を取ります。この要素は、コピーを取得するアロケータのconstructメソッドの呼び出しを使用して、ベクターにコピーされます。

C ++ 11では、このallocator_traits<>::construct関数を使用するには標準のコンテナーが必要です。これは、パラメーターを実際の構成に転送するvaradic関数です。allocator::constructこの特性関数は、その呼び出しが整形式である場合、(デフォルトで。特殊化することができます)メソッドを呼び出します。そうでない場合は、配置を試みますnew

これにより、新しいemplace機能が機能するようになります。

しかし、はい、標準ライブラリコンテナに含まれるオブジェクトは、実際には構築されたオブジェクトです。アロケータのconstructメソッドが呼び出されなくても。

于 2012-04-26T20:56:16.057 に答える
0

実装に依存しますが、一般的な実装ではstd::allocator::allocate、メモリのブロックを割り当てるために使用し、次に、コピーコンストラクター(またはC ++ 11では移動コンストラクター)を介してインスタンスを構築するために新しい配置を使用します。

要素が消去されると、基になるメモリが解放されていない場合でも、オブジェクトを破棄するためにそれらのデストラクタが直接呼び出されます。

于 2012-04-26T20:49:28.433 に答える