2011-05-04 6 views
8

Je veux créer un tableau qui contient des pointeurs vers de nombreux objets, mais je ne connais pas le nombre d'objets que je tiendrai, ce qui signifie que je dois allouer dynamiquement de la mémoire pour le tableau. J'ai pensé le code suivant:créer un tableau de pointeurs d'objet C++

ants = new *Ant[num_ants]; 
for (i=1;i<num_ants+1;i++) 
{ 
    ants[i-1] = new Ant(); 
} 

ants est défini comme Ant **ants; et Ant est une classe.

Cela fonctionnera-t-il?

+3

L'avez-vous essayé? –

+0

@Carl Norum, je ne peux pas l'essayer pour le moment, car je commence seulement à écrire le code, et il me manque encore beaucoup de parties. – SIMEL

+2

Vous voudrez peut-être changer votre boucle pour itérer de 0 à num_ants, et assigner aux fourmis [i]. Pas besoin de tout décaler de 1. –

Répondre

15

Will it work?

Oui.

Cependant, si possible, vous devez utiliser un vecteur:

#include <vector> 

std::vector<Ant*> ants; 
for (int i = 0; i < num_ants; ++i) { 
    ants.push_back(new Ant()); 
} 

Si vous devez utiliser un tableau alloué dynamiquement je préférerais cette syntaxe:

typedef Ant* AntPtr; 
AntPtr * ants = new AntPtr[num_ants]; 
for (int i = 0; i < num_ants; ++i) { 
    ants[i] = new Ant(); 
} 

Mais oubliez tout cela. Le code n'est toujours pas bon car il nécessite une gestion manuelle de la mémoire. Pour résoudre ce problème, vous pouvez modifier votre code:

std::vector<std::unique_ptr<Ant>> ants; 
for (auto i = 0; i != num_ants; ++i) { 
    ants.push_back(std::make_unique<Ant>()); 
} 

Et le meilleur de tout serait simplement ceci:

std::vector<Ant> ants(num_ants); 
+0

Pouvez-vous vraiment assigner le résultat de 'new' à un tableau? –

+0

@ Mark B: Bonne prise. Je l'ai réparé. – StackedCrooked

+0

Donc, fondamentalement 'new Ant * [num_ants]' est un faux appel, car il n'appelle pas du tout le constructeur? N'alloue que le tableau de pointeurs. C'est pourquoi le 'nouveau' semble être appelé deux fois. – Ciantic

4
std::vector<Ant> ants(num_ants); 
ants.resize(new_num_ants); 
+4

Si l'OP veut utiliser des pointeurs sur les fourmis, la déclaration serait: 'std :: vector ant_pointers (num_ants);' –

+0

Vous devrez également utiliser 'std :: generate' pour' new' tous les éléments respectifs. –

+0

J'ai voté parce que l'OP a mentionné directement qu'il voulait utiliser des pointeurs, ce qui, comme l'a mentionné @ThomasMatthews, nécessite une déclaration différente. Votre réponse est bonne pour un cas différent cependant. – Purefan

2
std::vector<Ant*> ants(num_ants); 
for (int i = 0; i != num_ants; ++ i) { 
    ants[i] = new Ant; 
} 

Ou si vous ne savez pas combien à l'avance:

std::vector<Ant*> ants; 
while (moreAntsNeeded()) { 
    ants.push_back(new Ant); 
} 

d'autre part, je pense que vous devez vous demander si Ant est un type d'entité ou d'une valeur . Si c'est une valeur, probablement vouloir sauter les pointeurs et l'allocation dynamique; S'il s'agit d'un type d'entité, vous devez prendre en compte la durée de vie de l'objet, et quand et où il sera supprimé.

2

Oui c'est l'idée générale. Cependant, il existe des alternatives. Etes-vous sûr que vous avez besoin d'un tableau de pointeurs? Un tableau d'objets de la classe Ant peut être suffisant. Le vous ne devez allouer le tableau:

Ant *ants = new Ant[num_ants]; 

En général, vous devriez préférer utiliser std::vector à l'aide d'un tableau. Un vecteur peut croître au besoin, et il va gérer la gestion de la mémoire pour vous.

Dans le code que vous avez posté, vous devez supprimer chaque élément de ants dans une boucle, puis supprimer le tableau lui-même, delete [] ant. Gardez à l'esprit la différence entre delete et delete [].

Un point de plus, puisque les indices de tableau en C++ sont basés 0, la convention suivante pour itérer sur les éléments:

for (i=0; i<num_ants; i++) 
{ 
    ants[i] = new Ant(); 
} 

Cela rend le code beaucoup plus lisible.

3

Avez-vous vraiment besoin de tenir pointeurs aux articles? Si vous pouvez utiliser des objets par valeur, une approche beaucoup plus simple consiste à utiliser un vecteur: std::vector<Ant> ants(num_ants);. Ensuite, non seulement vous n'avez pas à écrire en boucle, mais vous n'avez pas à vous soucier des fuites de mémoire provenant des pointeurs bruts et d'autres éléments de gestion d'objet.

Si vous avez besoin de pointeurs d'objet pour satisfaire une API, vous pouvez toujours utiliser vector pour le conteneur externe et allouer les objets manuellement.

struct CreateAnt 
{ 
    Ant* operator()() const { return new Ant; } 
}; 

std::vector<Ant*> ants(num_ants); // Create vector with null pointers. 
std::generate(ants.begin(), ants.end(), CreateAnt());