0

コンテナ Vector のようなベクターを作成しようとしています。

次に、次のように宣言しました。

Vector< A> Avector.

メモリの割り当て中に、 A にデフォルトのコンストラクターがないというコンパイル エラーが発生します。メモリを割り当てるために次のコードを書きました。

char *pBuffer = (char*) malloc(size*sizeof(T));
  T *array;
   for(int i = 0; i < size; i++)
  {
    (array+i) = new(pBuffer + i) T;
  }
  return array;

T はテンプレート変数です。

エラーは、A のデフォルト コンストラクターを作成していないのに、新しい配置で T のデフォルト コンストラクターを使用しているという事実によるものです。

知りたいのですが、メモリ割り当てがコンストラクターの署名に依存しないようにする方法はありますか。

4

2 に答える 2

2

In C++ calling new does two things:

  1. Allocates enough memory for the object being created &
  2. Provides oppurtunity to initialize the object properly by calling its constructor.

This is basic design feature of C++ as an language, pt 2 was added conspiciously to overcome malloc behavior of just allocating memory.

In short you cannot change this behavior.

于 2012-11-01T05:34:03.863 に答える
1

コンストラクターの署名に依存するのはメモリ割り当てではありません。それを行うのが初期化です。

あなたの例でも、割り当てはmallocコンストラクターを呼び出さずに実行されます。コンストラクターの使用を必要とするのは、(placement-new によって実行される) 初期化です。

コンストラクターを呼び出さずにユーザー定義オブジェクトを初期化する方法はありません。

ただし、少なくとも C++11 でできることは、コンストラクターに必要な引数を右辺値参照として受け取り、placement-new のコンストラクター呼び出しに渡す関数にコードを入れることです。 . このように、正しい引数を渡すのは関数の呼び出し元次第です。引数が渡されない場合、default-constructor が呼び出されます。

実際、これはnewのemplaceスタイル関数で使用されるテクニックstd::vectorです:

template< class... Args >
void emplace_back( Args&&... args );

これは可変個引数のテンプレートであるため、任意の数の引数 (ゼロ以上) が可能です。std::forward右辺値参照はそれらを受け取るために使用され、実装内では、引数がそのまま渡されるようにするためにコンストラクターを使用して呼び出す必要があります。

(array+i) = new (pBuffer + i) T(std::forward<Params>(args)...);

したがって、これにはまだコンストラクターを使用する必要がありますが、コンストラクターを選択するのは呼び出し元に任されています (引数を選択することによって)。既定のコンストラクターが使用できない場合、呼び出し元は、既定以外のコンストラクターを呼び出すために必要な引数を指定するだけで済みます。

于 2012-11-01T05:53:14.227 に答える