5

Fooというクラスがあるとしましょう。Fooにはデフォルトのコンストラクターがありません。コンストラクターFoo(int x、float y)があります。

Barはコンテナクラスです。Fooのインスタンスを含むベクトルが含まれています。

Bar::Bar(int numberOfFoos, int x, float y) {

foovector.resize (numberOfFoos);
for(int i = 0; i < numberOfFoos; i++) {
   **read below**
}

この時点で、Fooのコンストラクターを呼び出して、パラメーターintxとfloatyを渡します。Fooのコンストラクターは、xとyの値に応じて異なることを行います。

Fooにデフォルトのコンストラクターがあったとしましょう。ベクトルのサイズ変更関数は正確に何をしますか?デフォルトのコンストラクターを呼び出さずに、ベクトルのサイズを変更するだけですか?つまり、Foo型のn個の要素用にスペースが予約されていますが、それらは何にも初期化されていませんか?

この場合のように、それがない場合はどうなりますか?

forループでは、各Foo要素を次のように初期化します。

foovector[i].Foo(int x, float y);

しかし、このようにドットアクセス演算子を使用してコンストラクターを呼び出すことはできません。この時点では、コンストラクターがサイズ変更関数によって既に呼び出されているかどうかさえわかりません。

質問は、どうすればいいですか?

クラスのベクトルに関する別の関連する質問:

Fooには、floatを保持するベクトルがあります。float xパラメーターは、保持する必要のあるfloatの数です。Fooのコンストラクターには行があります

arrayofFloats.resize (x);

しかし、それはコンピュータがFooのサイズを事前に知らないことを意味します。そして、各fooは異なるサイズを持つことができます。それはFooのベクトルに問題を引き起こしませんか?各Fooが異なるサイズを持つことができる場合、特定のサイズのベクトルをどのように宣言できますか?

英語が下手でごめんなさい、それが十分にはっきりしていることを願っています。

ありがとうございました。

4

3 に答える 3

6

resizeスペースの予約には使用しないでください。代わりに、次を使用しますreserve

foovector.reserve(n);                          // reserves memory only, no object
                                               // constructions take place
for (std::size_t i = 0; i != n; ++i)
{
    foovector.emplace_back(12 * i, i / 3.0);   // pushes a new Foo(12*i, i/3.0)
}                                              // at the back of the vector
于 2013-03-18T17:59:33.497 に答える
1

私がこの権利を理解している場合は、Barコンストラクターが、毎回Fooコンストラクターへの同じ引数を使用してベクトル内にFooの多数のインスタンスを構築するようにします。Fooコンストラクターが、構築後にFooオブジェクトがすべて同一になるように機能する場合は、を使用できますstd::vector::assign(size_type n, const value_type& val)。この場合、value_typeはFooです。を呼び出すfoovector.assign( numberOfFoos, Foo(x, y) )と、ベクターは1つの一時的なFooオブジェクトをnumberOfFoos作成し、そのオブジェクトのコピーで自分自身を埋めます。assign()また、すべてのサイズ変更のニーズに対応します。

ただし、Fooコンストラクターにランダムな動作、静的カウンター、またはコンストラクターへの連続した呼び出しによって異なるオブジェクトが生成されるその他の何かが含まれる場合、コピーは必要なものではありません。

あなたの他の質問:

C ++では、すべての型のサイズが固定されています。(これが、ポリモーフィズムがポインターまたは参照渡しセマンティクスでのみ機能する理由です。)などの多くのクラスは、std::vector必要に応じて拡大または縮小できる追加のメモリーを管理します。これはすべて、ポインターを使用して舞台裏で行われます。ベクトルに含まれるデータなどの追加のメモリは、他のメモリ位置ではオフになっており、オブジェクトの実際のサイズには影響しません。vectorメソッド、、、size()およびはresize()、そのreserve()管理対象メモリで機能します。したがって、Fooオブジェクトは、そのベクトルに含まれるアイテムの数に関係なく、同じサイズになります。

于 2013-03-18T18:34:35.717 に答える
0

resize 新しい要素を初期化します具体的には、一時オブジェクトを値で初期化し(クラス型の場合はデフォルトのコンストラクターを使用)、それを使用して各要素をコピーで初期化します。

デフォルトのコンストラクターがない場合、またはコピー初期化できない場合は、使用できませんresize

ただし、reserveメモリ内のオブジェクトを初期化せずにメモリを予約するために使用できます。そして、そのスペースにpush_backorinsert要素を使用します。C++11 では、emplace_back要素をコピーする必要を回避するためにも使用できます。

foovector.reserve (numberOfFoos);
for(int i = 0; i < numberOfFoos; i++) {
   foovector.push_back(Foo(42, 1.23));   // C++03, requires copy constructor
   foovector.emplace_back(42, 1.23);     // C++11, doesn't require copy constructor
}

追加の質問について:

しかし、それはコンピュータが Foo のサイズを事前に知らないことを意味します

はい、そうです。ベクトルは、動的に割り当てられたメモリへのポインタを含む小さなオブジェクトです。そのサイズは固定されており、割り当てるメモリ量には依存しません。

于 2013-03-18T18:10:26.980 に答える