web-dev-qa-db-ja.com

スタックとヒープにオブジェクトの配列を作成する

次のコードを検討してください。

class myarray
{
    int i;

    public:
            myarray(int a) : i(a){ }

}

スタック上にmyarrayのオブジェクトの配列をどのように作成でき、ヒープ上にオブジェクトの配列を作成できますか?

15
Light_handle

スタック上にオブジェクトの配列を作成できます 経由:

myarray stackArray[100]; // 100 objects

そしてヒープ上 (または「フリーストア」):

myarray* heapArray = new myarray[100];
delete [] heapArray; // when you're done

ただし、メモリを自分で管理しないことをお勧めします。代わりに、 std :: vector :を使用してください

#include <vector>
std::vector<myarray> bestArray(100);

ベクトルは動的配列であり、(デフォルトで)ヒープから要素を割り当てます。††


クラスにはデフォルトのコンストラクターがないため、スタック上に作成するには、コンストラクターに何を渡すかをコンパイラーに通知する必要があります。

myarray stackArray[3] = { 1, 2, 3 };

またはベクトルを使用して:

// C++11:
std::vector<myarray> bestArray{ 1, 2, 3 };

// C++03:
std::vector<myarray> bestArray;
bestArray.Push_back(myarray(1));
bestArray.Push_back(myarray(2));
bestArray.Push_back(myarray(3));

もちろん、いつでもデフォルトのコンストラクターを指定できます。

class myarray
{
    int i;    
public:
    myarray(int a = 0) :
    i(a)
    {}
};

†衒学者の場合:C++には実際には「スタック」または「ヒープ」/「フリーストア」がありません。 「自動ストレージ」と「動的ストレージ」の期間があります。実際には、これはスタック割り当てとヒープ割り当てと一致します。

††スタックからの「動的」割り当てが必要な場合は、最大サイズを定義し(スタックストレージは事前にわかっています)、代わりにスタックを使用するようにベクターに新しいアロケーターを指定する必要があります。

42
GManNickG

C++ 11以降 std::array<T,size> は、スタックに割り当てられた配列で使用できます。 T[size]をラップしてstd::vectorのインターフェースを提供しますが、ほとんどのメソッドはconstexprです。ここでの欠点は、スタックがいつオーバーフローしたかがわからないことです。

std::array<myarray, 3> stack_array; // Size must be declared explicitly.VLAs

ヒープメモリで割り当てられた配列の場合は std::vector<T> を使用します。カスタムアロケータを指定しない限り、標準の実装ではヒープメモリを使用して配列メンバーを割り当てます。

std::vector<myarray> heap_array (3); // Size is optional.

どちらの場合も、配列を初期化するにはデフォルトのコンストラクターが必要なので、定義する必要があります

myarray::myarray() { ... }

Cの VLA またはC++のnewを使用するオプションもありますが、それらを使用するとコードがセグメンテーション違反やメモリリークを起こしやすくなるため、できるだけ使用しないでください。

6

クラスmyarray(スタック上またはヒープ上)のオブジェクトの配列を作成する場合、デフォルトのコンストラクターを定義する必要があります。

オブジェクトの配列を作成するときに、コンストラクターに引数を渡す方法はありません。

2
Tanuj

デフォルトのコンストラクターを使用せずにオブジェクトを作成する方法を知っていますが、スタック上でのみ作成できます。

a = 1..10を使用して、MyArrayクラスの10個のオブジェクトを作成するとします。

MyArray objArray[] = { MyArray[1], MyArray[2]......MyArray[10]}

デストラクタはスタックに作成されるため、デストラクタを呼び出す必要はありません。

0
Alok