C++ vecteurs de classes avec des constructeurs
//Using g++ and ubuntu.
#include <vector>
using namespace std;
Définir une classe:
class foo(){
(...)
foo(int arg1, double arg2);
}
Constructeur:
foo::foo(int arg1, double arg2){
(...) //arrays whose length depend upon arg1 and arg2
}
Je voudrais faire quelque chose comme ceci:
vector<foo> bar(10); //error: no matching function for call to 'foo::foo()'
bar[0] = new foo(123, 4.56);
(...)
Une autre méthode (que j'aime moins) est d'utiliser push_back:
vector<foo> bar; //works
bar.push_back(new foo(123, 4.56)); //throws similar error.
//Omitting the "new" compiles but throws a "double free or corruption (fasttop)" on runtime.
Je veux les différents éléments du vecteur d'être construit différemment, donc je ne veux pas utiliser la "séquence Répétitive constructeur".
Ce qui devrait être fait?
OriginalL'auteur Kevin Kostlan | 2010-08-09
Vous devez vous connecter pour publier un commentaire.
Pourquoi êtes-vous à l'aide de
new
lorsque aucune dynamique de la mémoire doit être créé? De cours à l'aide denew
échoue, il en résulte unfoo*
quandpush_back
accepte unfoo
. (C'est ce que vous avez un vecteur d', après tout.)Quel est le problème avec
push_back
? Si vous souhaitez réserver de la mémoire à l'avant, utilisezreserve()
; de fournir un numéro dans le constructeur devector
fait que de nombreuses copies de la deuxième paramètre (qui est implicitementfoo()
, qui ne fonctionne pas donc vos erreurs), ce qui n'est pas le même que tout simplement réserver de la mémoire.Si faire les choses correctement (pas de
new
) se bloque, la faute est dans votre code et pas de vecteur. Vous n'avez probablement pas écrit une classe qui gère les ressources.* (Rappelez-vous Les Trois Grands, utilisez le copie-et-swap idiome.)*je dis cela parce que vous vous dites "
//arrays whose length depend upon arg1 and arg2
", ce qui je pense signifie que vous aveznew[]
dans votre classe, quelque part. Sans le Grand les Trois, votre gestion des ressources sera un échec.Vous ne devriez pas être la gestion des ressources de toute façon, les classes ont une responsabilité. Cela signifie qu'il doit être un tableau dynamique, ou l'utilisation d'un tableau dynamique, mais pas les deux à gérer et à utiliser un tableau dynamique. Afin de factoriser les ressources dans leur propre classe, et ensuite faire une autre classe (la vôtre) qui les utilise. Un tableau dynamique est un
std::vector
, de sorte que vous êtes déjà fait avec qui. Tout de temps vous avez besoin d'un tableau dynamique, utilisez unvector
; il n'y a jamais une raison de ne pas.OriginalL'auteur GManNickG
C'est un échec parce que le
std::vector
constructeur que vous appelez estComme vous pouvez le voir, il essaye de remplir le vecteur avec les 10 appels au constructeur par défaut de
foo
qui n'existe pas.Aussi, tous vos exemples mettant en vedette
new
va échouer parce que le vecteur attend un objet de typefoo
, pasfoo *
. En outre, l'évolution devector<foo *>
échoue trop, sauf si vous avez manuellementdelete
chaque membre avant d'effacer le vecteur. Si vous voulez vraiment aller de l'allocation dynamique de la mémoire de l'itinéraire créer unvector< shared_ptr< foo > >
.shared_ptr
est disponible dans le Bibliothèques Boost ou si votre compilateur comprend TR1 bibliothèques, il va être présent dans le<memory>
d'en-tête dans lestd::tr1
espace de noms ou si votre compilateur a le C++0x bibliothèques il sera disponible dans lestd
espace de noms.Ce que vous devriez faire est la suivante:
Cela seul ne fonctionne pas, mais j'ai besoin d'avoir le big 3.
Je soupçonne que vous devez utiliser
std::vector
de sorte que vous n'avez pas. Faire facteur, les ressources provenant de l'utilisation, ne pas faire les deux.OriginalL'auteur Praetorian
std::vector toujours créer des éléments basés sur le constructeur par défaut qui vous n'avez pas de définir dans l'extrait ci-dessus.
la méthode push_back est confrontée à un double problème parce que vous n'avez pas à gérer le constructeur de copie.
OriginalL'auteur YeenFei