web-dev-qa-db-fra.com

Création d'un tableau d'objets sur la pile et le tas

Considérons le code suivant:

class myarray
{
    int i;

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

}

Comment créer un tableau d'objets myarray sur la pile et comment créer un tableau d'objets sur le tas?

14
Light_handle

Vous pouvez créer un tableau d'objets sur la pile via:

myarray stackArray[100]; // 100 objects

Et sur le tas (ou "freestore"):

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

Mais il vaut mieux ne pas gérer la mémoire vous-même. Au lieu de cela, utilisez un std :: vector :

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

Un vecteur est un tableau dynamique qui (par défaut) alloue des éléments du tas.††


Comme votre classe n'a pas de constructeur par défaut, pour la créer sur la pile, vous devez indiquer au compilateur ce qu'il doit transmettre au constructeur:

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

Ou avec un vecteur:

// 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));

Bien sûr, vous pouvez toujours lui donner un constructeur par défaut:

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

† Pour les pédants: C++ n'a pas vraiment de "pile" ou de "tas"/"freestore". Ce que nous avons est "durée de stockage automatique" et "stockage dynamique". En pratique, cela s'aligne avec l'allocation de pile et l'allocation de tas.

†† Si vous souhaitez une allocation "dynamique" à partir de la pile, vous devez définir une taille maximale (le stockage de la pile est connu à l'avance), puis attribuer à vector un nouvel allocateur afin qu'il utilise plutôt la pile.

39
GManNickG

Depuis C++ 11, std::array<T,size> est disponible pour les tableaux alloués sur la pile. Il encapsule T[size] en fournissant l'interface de std::vector, mais la plupart des méthodes sont constexprname__. L'inconvénient est que vous ne savez jamais quand vous débordez la pile.

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

Pour les matrices allouées avec de la mémoire de tas, utilisez std::vector<T> . Sauf si vous spécifiez un allocateur personnalisé, la mise en œuvre standard utilisera de la mémoire de segment pour allouer les membres du groupe.

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

Note que dans les deux cas, un constructeur par défaut est requis pour initialiser le tableau, vous devez donc définir

myarray::myarray() { ... }

Il existe également des options pour utiliser VLA de C ou newde C++, mais évitez de les utiliser autant que possible car leur utilisation rend le code vulnérable aux erreurs de segmentation et aux fuites de mémoire.

4
Alexander Solovets

Si vous créez un tableau d'objets de classe myarray (sur pile ou sur tas), vous devrez définir un constructeur par défaut.

Il n'y a aucun moyen de passer des arguments au constructeur lors de la création d'un tableau d'objets.

2
Tanuj

Je sais comment créer un objet avec le constructeur par défaut, mais uniquement sur pile:

Supposons que vous souhaitiez créer 10 objets pour la classe MyArray avec a = 1..10:

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

Pas besoin d'appeler le destructeur, car ils sont créés dans la pile.

0
Alok