Создание массива объектов в стеке и куче

Рассмотрим следующий код:

class myarray
{
    int i;

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

}

Как вы можете создать массив объектов myarray в стеке и как вы можете создать массив объектов в куче?

Ответ 1

Вы можете создать массив объектов в стеке с помощью:

myarray stackArray[100]; // 100 objects

И на куче (или "freestore" ):

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)
    {}
};

† Для педантов: у С++ на самом деле нет "стека" или "кучи" / "freestore". У нас есть время "автоматического хранения" и "динамического хранения". На практике это выравнивается с распределением стека и распределением кучи.

†† Если вам требуется "динамическое" выделение из стека, вам нужно определить максимальный размер (хранение стека известно заранее), а затем дать вектору новый распределитель, чтобы вместо этого использовать стек.

Ответ 2

Так как С++ 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 VLAs или С++ new, но вы должны воздерживаться от их использования как можно больше, поскольку их использование делает код подверженным ошибкам сегментации и утечкам памяти.

Ответ 3

Если вы создаете массив объектов класса myarray (либо в стеке, либо в куче), вам нужно будет определить конструктор по умолчанию.

Невозможно передать аргументы конструктору при создании массива объектов.

Ответ 4

Я знаю, как создать объект из конструктора по умолчанию, но только в стеке:

Предположим, вы хотите создать 10 объектов для класса MyArray с помощью a = 1..10:

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

Не нужно вызывать деструктор, потому что они созданы в стеке.

Ответ 5

#include <stdio.h>
class A
{
public:
  A(int a){ 
       printf("\nConstructor Called : %d\n",a); 
       aM = a;
      }  
  ~A(){ 
    printf("\ndestructor Called : %d\n",aM);
}
private:
  int aM;
};

int main()
{                                                                                                   
  A **a = new A*[10];
  for (int i = 0;i<10;i++)
    a[i] = new A(i+1);
    for (int i = 0;i<10;i++)
      delete a[i];// = new A(i+1);                                                                                    

  delete []a;
}