Wie nennt man einen Konstruktor für Globale Objekte für arrays von Objekten, und Objekte innere Klassen/structs?
Wie würden Sie rufen den Konstruktor der folgenden Klasse in diesen drei Situationen: Globale Objekte, arrays von Objekten, und die Objekte in eine andere Klasse/struct?
Die Klasse mit dem Konstruktor (in allen drei Beispielen):
class Foo {
public:
Foo(int a) { b = a; }
private:
int b;
};
Und hier sind meine versuche bei Aufruf dieses Konstruktors:
Globale Objekte
Foo global_foo(3); //works, but I can't control when the constructor is called.
int main() {
//...
}
Arrays von Objekten
int main() {
//Array on stack
Foo array_of_foos[30](3); //doesn't work
//Array on heap
Foo *pointer_to_another_array = new Foo(3) [30]; //doesn't work
}
Dort bin ich versucht, rufen Sie den Konstruktor für alle Elemente des arrays, aber ich würde auch gerne wissen, wie Sie es nennen, auf den einzelnen Elementen.
Objekte in Klassen/structs
class Bar {
Foo foo(3); //doesn't work
};
int main() {
Bar bar;
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Globale Objekte
Deiner ist der einzige Weg. Auf der anderen Seite, versuchen, dies zu vermeiden. Es ist besser, um Funktionen (oder auch andere Objekte) als Fabriken statt. Auf diese Weise können Sie Steuern die Zeit der Schöpfung.
Arrays von Objekten
Gibt es keine Möglichkeit das direkt tun. Nicht-POD-Objekte werden immer default-konstruiert.
std::fill
ist oft eine große Hilfe. Sie möchten vielleicht auch einen Blick in allocators undstd::uninitialized_fill
.Objekte in Klassen/structs
Verwenden, die Initialisierung der Listen in den Konstruktor:
Statischen Elemente müssen tatsächlich außerhalb der Klasse definiert:
Korrigieren einige Missverständnisse über globals:
Nicht, was ich empfehlen würde, aber: So eine einfache Lösung ist, um alle globals in einer einzigen compilation unit.
Alternativ können Sie zwicken die Verwendung der Funktion statische Variablen.
Grundsätzlich können Sie eine Funktion liefert eine Referenz auf die global Sie wollen (definieren der global innerhalb der Funktion). Es wird erstellt bei der ersten Verwendung (und zerstört in umgekehrter Reihenfolge der Erstellung).
Konrad-Antwort ist OK, nur ein puntualization über die arrays....
Es ist ein Weg, um ein array von Elementen(keine Zeiger) und hier folgt es:
Dieser Ansatz wird hier beschrieben: http://www.amazon.com/gp/product/0321334876?ie=UTF8&tag=aristeia.com-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321334876
Für den globalen Fall gibt es keine Möglichkeit, zu kontrollieren, Wann es aufgerufen wird. Die C++ - spec sagt im wesentlichen, es wird aufgerufen werden, bevor main() und wird zerstört werden, irgendwann danach. Andere als die, dass " der compiler ist frei, zu tun, wie es ihm gefällt.
In der ersten array-Fall, erstellen Sie ein statisches array von Foo-Objekte. Standardmäßig wird jeder Wert im array wird initialisiert mit dem Standard-Konstruktor von Foo(). Es gibt keine Möglichkeit mit einem raw-C++ - array zu zwingen, einen bestimmten überladenen Konstruktor aufgerufen werden. Sie können ableiten, ein bisschen Steuern, indem man zu einem Vektor anstelle eines Arrays. Die Vektor-Konstruktor hat einen überladenen Konstruktor vector(Größe,defaultValue), die das erreichen, was Sie suchen. Aber in diesem Fall müssen Sie vorsichtig sein, denn statt des Aufrufs Foo(3) es wird der Aufruf von Foo(const Foo& andere), wo andere Foo(3).
Dem zweiten array-Fall ist sehr ähnlich zu dem ersten Fall. Der einzige wirkliche Unterschied ist, wo der Speicher reserviert (auf dem heap statt auf dem stack). Es hat die gleiche Einschränkung in Bezug auf den Aufruf für den Konstruktor.
Enthaltenen Fall ist, ist eine andere Frage. C++ hat eine klare Trennung zwischen der definition eines Feldes innerhalb eines Objektes und der Initialisierung des Feldes. Zu bekommen dies funktioniert in C++ werden Sie brauchen, um Ihre Bar-definition der folgenden
Scheint es die Allgemeine Kernaussage in diesem thread, dass Sie nicht initialisiert werden Mitglieder eines Arrays anderen als den default-Konstruktor. Eine Antwort, die auch erzeugt eine andere Art, nur zu nennen ein weiterer Konstruktor. Obwohl Sie können (, wenn das array nicht Teil, als ein Mitglied einer Klasse!):
Art, jedoch kopiert werden muss-in der Lage: Die Elemente gegeben sind, - Kopie-initialisiert, in die die Mitglieder des Arrays.
Für arrays als Mitglieder in den Klassen, es ist das beste, um Behälter verwenden, derzeit:
Mithilfe der
placement-new
beschriebenen Verfahren von andy.gurin ist eine option, zu. Aber beachten Sie, es wird die Dinge zu komplizieren. Sie haben zu nennen, Destruktoren selbst. Und wenn jeder Konstruktor wirft, während Sie immer noch den Aufbau des array, dann brauchen Sie, um herauszubekommen, wo Sie aufgehört haben... Insgesamt, wenn Sie wollen, um arrays in Ihrer Klasse, und initialisieren möchten, verwenden Sie einesstd::vector
ist eine einfache Wette.Bau von arrays von Objekten:
Können Sie ändern Ihre ursprüngliche Beispiel durch die Verwendung von default-Parametern.
Derzeit nur die default-Konstruktor wird unterstützt.
Dies ist etwas, das angegangen werden, die nächste version (weil jeder fragt diese Frage)
C++0X-Initialisierer-Listen lösen dieses problem für die arrays von Objekten Fall. Sehen diese Herb Sutter blog-Eintrag, wo er beschreibt Sie im detail.
In der Zwischenzeit können Sie möglicherweise das problem umgehen, etwa so:
Hier, die
Foo_3
- Klasse ist ausschließlich für den Zweck der Berufung derFoo
Konstruktor mit dem richtigen argument. Man konnte es eine Vorlage auch:Wieder diese möglicherweise nicht genau das tun, was Sie wollen, aber einige Denkanstöße.
(Beachten Sie auch, dass in Ihrem
Foo
Klasse, die Sie sollten wirklich in die Gewohnheit, mit Element-Initialisierer-Listen anstelle von Zuweisungen im Konstruktor, als je mein Beispiel oben)Ich denke, es gibt zwei Möglichkeiten, um sicherzustellen, dass die Globale Klasse von Objekten Konstruktoren aufgerufen werden sicher an der Zeit, Ihre "Schöpfung":
Erklären Sie in einem namespace, und stellen Sie diesen namespace Global zugänglich.
Machen es zu einem globalen Zeiger auf das class-Objekt, und weisen Sie eine neue Objekt-Klasse in main(), erteilt-code für den anderen globalen Objekte Konstruktoren, Zugriff auf das Objekt ausgeführt werden soll, bevor diese.
Nur meine zwei Cent.