Initialize array im Konstruktor übergeben, ohne mit dem default-Konstruktor oder Abtretung
Betrachten:
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 */
{}
};
Ich war davon ausgegangen, dass Arbeit da bin ich mit C++0x support in GCC4.3, die angeblich unterstützt initialiser Listen. Keine Freude.
Ich habe eine Klasse A, die hat keinen default-Konstruktor. Dies ist nicht verhandelbar. Zuordnung post-Standard ist keine option.
Ich versuche zu erstellen, B, die verwendet A. B::foo kann nicht std::vector.
Wie kann ich Sie initialisieren B::foo
im B(...)
, die Konstruktion Ihrer Elemente genau einmal?
Im moment bin ich condidering ersetzen von B mit
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) {}
};
Oder sogar mit char foo [2*sizeof(A)]
mit placement-new -- IGITT!
Sicherlich gibt es eine richtige Art und Weise, dies zu tun?
Nur lassen Sie wissen, dass ich formatiert Ihren code-Blöcke ein bisschen mehr schön mit der "0101" - Taste.
InformationsquelleAutor spraff | 2010-09-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Leider gibt es wirklich keine ordentliche, saubere Art und Weise, dies zu tun. Betrachten Sie es so etwas wie eine Sprache, die Einschränkung, dass die Ergebnisse aus einer misslichen Vermischung von C++ Konstruktoren und C-style arrays. Die standard C++11 löst dieses Problem, aber bis dahin müssen Sie sich für einen workaround.
Seit
A
hat kein default Konstruktor, wird ein möglicher work-around ist, um ein array vonA*
Zeiger und dann die Schleife über das array, und initialisieren Sie jeweils mitnew
. (Natürlich, vergessen Sie nicht zudelete
jedes Element im array in B ' s destructor, oder nutzen Sie einfach die smart-Pointer.)Ich bin mir ziemlich sicher, dass GCC 4.3 ist C++0x-Erweiterung nicht unterstützen Initialisierer-Listen. Siehe gcc.gnu.org/projects/cxx0x.html
InformationsquelleAutor Charles Salvia
Können Sie
boost::array
. Es hat einen einfachen, nativen array im inneren, also es hat immer noch den gleichen Speicher-layout wie in deinem Beispiel.Wenn Sie nicht über boost können Sie erstellen Sie Ihre eigenen
array
- Klasse oderstd::tr1
wenn dein compiler hat esDas ist alles, was Sie brauchen, aber Sie können fügen Sie die üblichen
begin
,end
,size
Funktionen und so weiter, um es bequemer zu verwenden.danke. Obwohl jede Kopie beteiligten außer den unvermeidlichen Kopien
x
undy
ina
sind förderfähig optimiert werden: (1) Kopie der lokalena
an die return-Wert, und (2) kopieren des return-Wert temporär infoo
.Gut, wenn spraff hat einen compiler, die C++0x, nicht, die kommen auch mit
std::array
?InformationsquelleAutor Johannes Schaub - litb
Sollte es in C++0x, aber g++ 4.5.0 beschwert sich mit "bad array-Initialisierung". Wenn Sie ersetzen
A foo[2]
mitstd::vector<A> foo
es kompiliert.unter meinen Kommentar zurück. Scheint, es funktioniert nur für nicht-Klasse-element-Typen auch auf GCC4.6 🙁
Klingt wie ein g++ - bug zu mir.
InformationsquelleAutor fredoverflow
Ihre Frage ist ähnlich wie diese Vorherige Frage: C++: Konstruktor-Initialisierer für arrays
Ihre wichtigsten Vorschlag (zwei Mitglieder
foo_a
undfoo_b
) ist wahrscheinlich der beste Weg, Dinge zu tun, vorausgesetzt, dass Sie brauchen nur zwei Elemente.Es gibt keine Möglichkeit, das initialisieren von array-Elementen mit nichts, aber der Typ Standard-Konstruktor in einer Initialisierer-Liste, wie Sie versuchen zu tun, in Ihrem Beispiel.Edit: Sorry, ich wollte nicht sehen, dass Sie wurden mit Hilfe von C++0x. In C++0x-Sie sollten in der Lage sein zu initialisieren, wie Sie wollte, zu tun, vorausgesetzt, A ist kopierbar oder verschiebbar. Ich weiß nicht, wie GCC 4.3 ist die Unterstützung für diese, obwohl.Vorsichtig mit
char
arrays und placement-new -char
arrays sind nicht unbedingt richtig ausgerichtet, um den Bau einerA
, und dies zu tun, kann nicht definiertes Verhalten zur Folge.Einige andere Vorschläge:
auto_ptr
oderboost::scoped_ptr
, und legen die Objekte auf dem heap mitnew A(args...)
.boost::optional<A>
behandelt die Standard-Konstruktion und die Ausrichtung problem für Sie, aber immer noch im wesentlichen speichert die Objekte A in der B-Objekt die richtige ist.InformationsquelleAutor Doug