3

C ++でのベクトルへのオブジェクトの追加とベクトルへのポインターの追加.

例:

std::vector<Size> buildings;
Size building(buildingWidth, buildingHeight);
buildings.push_back(building);

VS

std::vector<Size*> buildings;
Size *building = new Size(buildingWidth, buildingHeight);
buildings.push_back(building);

メモリ/パフォーマンスの点でどちらが優れていますか?

最初のものは基本的にスタック上にオブジェクトを作成し、それをベクターに追加します。したがって、インスタンス化が 1 つで、その後にベクターへのコピーが 1 つあります。

2 つ目は、ヒープ上にオブジェクトを作成します。インスタンス化は 1 つありますが、ベクターへのコピーはありません。

私は正しいですか?

4

6 に答える 6

4

2 つのストレージ手法は、異なる目的を果たします。

最初の手法は、ポリモーフィックな動作を必要とせず、オブジェクトのスライスが問題にならない「同種の」ベクトルで役立ちます。その見返りに、リソース管理が自動化されます。ベクトルがコピーを作成するため、オブジェクトの所有権について心配する必要はありません。ベクターのサイズが変更されるたびに、コピーも内部的に作成されます。この考慮事項により、オブジェクトのコピーに多少のコストがかかる場合、最初のオプションはあまり魅力的ではなくなります。この考慮事項が適用されるかどうかを確認するには、コードをプロファイリングする必要があります。

2 番目の手法では、メモリを管理する必要があります。ポインターのベクトルからオブジェクトを削除することを決定するたびに、所有権を取得する必要があり、最終的にdeleteはオブジェクトを明示的に取得する必要があります。スマート ポインターを使用して、リソース管理の問題に対処できます。この手法により、コピーを回避できますが、コンテナー内の要素にアクセスするプロセスが少し複雑になります。

于 2013-05-29T15:05:17.470 に答える
0

なぜこれをしないのですか:

std::vector<Size> buildings;
buildings.resize(1);
buildings[0].setSize(buildingWidth, buildingHeight);

この方法では、コンストラクターは 1 回だけ呼び出され、自分でメモリを管理する必要はありません。std::vector<Size *>私が考えることができる唯一の欠点は、幅と高さが2回設定されることです(コンストラクターで1回、「setSize」で1回)が、アプローチを使用しない限り、それから逃れることはできないと思います.

于 2013-05-29T15:08:51.540 に答える
0

オブジェクトのサイズとオブジェクトのコピー セマンティクスに応じて、どちらも通常は比較的類似したパフォーマンスを発揮します。メモリ リークとユーザビリティに関しては、通常、最初の方法の方がはるかに優れています。

于 2013-05-29T15:00:39.993 に答える
0

それは本当にサイズの性質に依存します。オブジェクトが大きい場合 (コピー コンストラクターが多くの作業を行う必要がある場合)、ポインターのアイデアを検討できます。ただし、メモリを自分で制御する必要があり、標準のコンテナーから継承することはお勧めできません (仮想デストラクタがないため)。

Size クラス (std::string の実装に少し似ています) で書き込みセマンティクスのコピーを作成できます。

または、デフォルトのコンストラクターと Size の swap メソッドを用意します (とにかく std::vector でデフォルトのコンストラクターを使用する必要があります)。swap メソッドを使用して、新しい Size オブジェクトをベクター内の位置にスワップします。

時期尚早の最適化は諸悪の根源である」(attrib.Tony Hoare) に基づいて、私は最も単純なアプローチに固執します。つまり、最初のアイデアで、それがどうなるか見てみましょう。

于 2013-05-29T15:05:01.580 に答える
0

それは本当に

  • そのベクトルに対して実行される操作
  • オブジェクトがベクターにプッシュされる頻度

ベクトルに対して何らかの種類の変更可能な操作を行う場合は、shared_ptr タイプを使用することをお勧めします。

最終的に、どのような種類のパフォーマンス関連の質問でも、アプリケーションの条件下で自分でテストするのが最善です.

于 2013-05-29T15:05:56.570 に答える
-1

ポインターのベクトルを使用する 2 番目のアプローチは、2 つのオプションのうち優れていると思います。2つの単純な理由から

  1. オブジェクトのサイズが大きい場合、オブジェクトのベクトルを使用すると、不要なコピーが追加されます。
  2. オブジェクトのベクトルを引数としてメソッドに渡し、ベクトル内の任意のオブジェクトを変更しようとすると、すべての場所に反映されません。
于 2013-05-29T15:12:26.337 に答える