Initialiser dans le constructeur, sans l'aide de constructeur par défaut ou de la cession
Considérer:
struct A {
A (int);
A (const A &);
};
struct B {
A foo [2];
B (const A & x, const A & y)
: foo {x, y} /* HERE IS THE PROBLEM */
{}
};
Je m'attendais à ce genre de travail depuis que je suis à l'aide de C++0x soutien dans GCC4.3, qui aurait soutient initialiser les listes. Pas de joie.
J'ai une classe A qui n'a pas de constructeur par défaut. Ce n'est pas négociable. Affectation post-défaut n'est pas une option.
Je suis en train de créer B, qui utilise A. B::foo peut pas être std::vector.
Comment puis-je initialiser B::foo
dans B(...)
, la construction de ses éléments exactement une fois?
En ce moment, je suis condidering remplaçant B avec
struct B {
A foo_a;
B foo_b;
A * foo () {
assert ((&foo_b) - *&foo_a) == 1);
return &foo_a;
}
B (const A & x, const A & y) : foo_a(x), foo_b(y) {}
};
Ou même en utilisant char foo [2*sizeof(A)]
avec la mise en place de la nouvelle -- BEURK!
Il y a certainement une bonne façon de le faire?
Juste pour vous informer que j'ai formaté votre blocs de code un peu plus de bien à l'aide de la "0101" bouton.
OriginalL'auteur spraff | 2010-09-26
Vous devez vous connecter pour publier un commentaire.
Malheureusement, il n'y a vraiment pas propre façon de le faire. Considérer quelque chose de langue, une limitation qui résulte d'une drôle de mélange de C++ les constructeurs et C le style des tableaux. Le C++11 norme traite de cette question, mais jusqu'alors, vous aurez à régler pour une solution de contournement.
Depuis
A
n'a pas de constructeur par défaut, il est possible de contourner cette difficulté est d'avoir un tableau deA*
pointeurs, puis une boucle sur le tableau et initialiser chacun avecnew
. (Évidemment, n'oubliez pas dedelete
chaque élément de la matrice dans B est destructeur, ou simplement utiliser des pointeurs intelligents.)Je suis sûr que GCC 4.3 C++0x extension ne prend pas en charge l'initialiseur de listes. Voir gcc.gnu.org/projects/cxx0x.html
OriginalL'auteur Charles Salvia
Vous pouvez utiliser
boost::array
. Il a un simple tableau natif à l'intérieur, il a toujours la même disposition de la mémoire comme dans votre exemple.Si vous n'avez pas de coup de pouce que vous pouvez créer votre propre
array
de la classe ou de l'utilisationstd::tr1
si votre compilateur aC'est tout ce dont vous avez besoin, mais vous pouvez ajouter l'habitude
begin
,end
,size
fonctions et ainsi de suite pour le rendre plus confortable à utiliser.merci. Bien que chaque copie, sauf l'inévitable copies de
x
ety
ena
sont admissibles à être optimisé: (1) copie de locauxa
dans la valeur de retour, et (2) copie de la valeur de retour temporaire dansfoo
.Eh bien, si spraff a un compilateur supportant C++0x, ne faut-il pas aussi de venir avec
std::array
?OriginalL'auteur Johannes Schaub - litb
Il faut travailler dans C++0x, mais g++ 4.5.0 se plaint de "mauvais initialiseur de tableau". Si vous remplacez
A foo[2]
avecstd::vector<A> foo
, il compile.prenant mon commentaire à l'arrière. Il semble qu'il ne fonctionne que pour les non-classe de types d'éléments, même sur GCC4.6 🙁
Sonne comme un g++ bug pour moi.
OriginalL'auteur fredoverflow
Votre question est semblable à cette question précédente: C++: constructeur initialiseur pour les tableaux
Votre principale suggestion (faire deux membres
foo_a
etfoo_b
) est probablement la meilleure façon de faire les choses, à condition que vous avez besoin de deux éléments.Il n'y a aucun moyen de l'initialisation des éléments du tableau avec rien, mais le type du constructeur par défaut dans une liste d'initialiseur, comme vous essayez de le faire dans votre exemple.Edit: Désolé, je ne savais pas que vous étiez à l'aide de C++0x. Dans C++0x, vous devriez être en mesure d'initialiser que vous avez voulu faire, à condition que l'Un est copiable ou mobiliers. Je ne sais pas à propos de GCC 4.3 soutien pour cela, mais.Être prudent en utilisant
char
tableaux et le placement de la nouvelle -char
tableaux ne sont pas nécessairement alignés correctement, afin de construire unA
, et cela peut entraîner un comportement indéfini.Quelques autres suggestions:
auto_ptr
ouboost::scoped_ptr
, et de créer l'Un des objets sur le tas à l'aide denew A(args...)
.boost::optional<A>
, qui gère le défaut de la construction et de l'alignement problème pour vous, mais encore essentiellement des magasins de l'Un des objets à l'intérieur de l'objet B bon.OriginalL'auteur Doug