PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Objekte auf dem Heap


liquid
2003-01-03, 02:33:07
N'abend, man ist das schon wieder spät *guck auf die Uhr*

Sprache: C/C++

Frage: Ist es möglich bei der Erstellung von ObjekteN (Mehrzahl ist hier wichtig), diese gleich zu initialisieren??

Sagen wir mal ich habe ein Objekttyp mit 2 Konstruktoren:
object();
object(const another_object& X);

Erstmal will ich ein Objekt auf dem Heap erzeugen...
object* dings = new object; // 1. Konstruktor wird benutzt!

another_object temporaer; // Zum Init vom nächsten object!
object* dings2 = new object(temporaer);

So, das funzt auch alles schön, aber folgendes hab ich irgendwie noch nicht hinbekommen.

object* dings = new object[3]{temp1, temp1, temp3};

Der Syntax (wenn es überhaupt geht) ist bestimmt falsch, aber ich will folgendes machen. temp1, temp2 und temp3 sind Objekte des typ another_object, mit denen ich ja den object-Tpy initialiseren will. So soll der 2. Konstruktor aufgerufen werden, der das Objekt mit einem von außen zugeführten Objekt initialisiert.
Mal das was funzt:

object* dings = new object[3]; // 1. Konstruktor wird benutzt
dings[0] = object(temp1); // 2.Konstruktor
dings[1] = object(temp2); // 2.Konstruktor
dings[2] = object(temp3); // 2.Konstruktor

Achtung: Der operator=, Kopierkonstruktor und alles andere sind vorhanden und funzen auch super.

Nun ist es bei dem oben aufgeführten Code ja so, dass der Konstruktor gleich 6 Male aufgerufen wird. Einmal wenn das Array erzeugt wird (3x 1.Konstruktor) und dann wenn das Array initialisiert wird (3x 2.Konstruktor).

Frage: Wie macht man sowas? Geht es, und wenn, wie genau?

Grund: Wie immer, Performance...*g*

Bin für jede Hilfe dankbar!!

cya
liquid

Xmas
2003-01-03, 03:59:15
Originally posted by liquid
object* dings = new object[3]; // 1. Konstruktor wird benutzt
dings[0] = object(temp1); // 2.Konstruktor
dings[1] = object(temp2); // 2.Konstruktor
dings[2] = object(temp3); // 2.Konstruktor
???

object* dings = new object[3]; // 1. Konstruktor wird benutzt
dings[0] = temp1;
dings[1] = temp2;
dings[2] = temp3;

tut doch genau dasselbe. Und wenn der Default Constructor leer ist, geht es eigentlich nicht schneller. Nur die Schreibweise ist etwas umständlich, aber der einzige Weg das zu umgehen wäre IMO eine Funktion mit Ellipse (...) also variabler Anzahl an Parametern, die die Objekte einzeln initialisiert.

liquid
2003-01-03, 14:44:20
Originally posted by Xmas

???

object* dings = new object[3]; // 1. Konstruktor wird benutzt
dings[0] = temp1;
dings[1] = temp2;
dings[2] = temp3;

tut doch genau dasselbe. Und wenn der Default Constructor leer ist, geht es eigentlich nicht schneller. Nur die Schreibweise ist etwas umständlich, aber der einzige Weg das zu umgehen wäre IMO eine Funktion mit Ellipse (...) also variabler Anzahl an Parametern, die die Objekte einzeln initialisiert.

Genau das will ich ja verhindern. Außerdem funzt der Code oben sowieso nicht, da temp1 bis temp3 vom Typ another_object sind und der operator= nur mit Objekten des Typs object funzt. Selbst wenn er das machen würde, hätte ich immer noch die doppelte Initialiserung. Denn dem 2.Konstruktor übergebe ich ja eine Referenz, die MUSS er kopieren, da die Möglichkeit besteht, dass das Objekt (was ja auf dem Stack existiert) den Gültigkeitsbereich verlässt.

Noch was zu der Konstruktoren. Beide sind nicht leer, einmal wird inner von Konstruktor 1 einer privaten Variable ein Standardwert zugewiesen (ich will nicht, dass Variablen innerhalb von Objekten undefiniert bleiben) und im 2. Konstruktor wird einfach ein Wert aus tempX geholt und damit die Variable innerhalb des Objektes initialisiert.
Das sind pro erstelltem Objekt zwei Konstruktoraufrufe, einmal mit den Standardwerten und dann nochmal mit der eigentlichen Initialisierung. Und genau das will ich verhindern...:(

cya
liquid

Xmas
2003-01-03, 17:57:14
Originally posted by liquid
Genau das will ich ja verhindern. Außerdem funzt der Code oben sowieso nicht, da temp1 bis temp3 vom Typ another_object sind und der operator= nur mit Objekten des Typs object funzt. Selbst wenn er das machen würde, hätte ich immer noch die doppelte Initialiserung. Denn dem 2.Konstruktor übergebe ich ja eine Referenz, die MUSS er kopieren, da die Möglichkeit besteht, dass das Objekt (was ja auf dem Stack existiert) den Gültigkeitsbereich verlässt.

Noch was zu der Konstruktoren. Beide sind nicht leer, einmal wird inner von Konstruktor 1 einer privaten Variable ein Standardwert zugewiesen (ich will nicht, dass Variablen innerhalb von Objekten undefiniert bleiben) und im 2. Konstruktor wird einfach ein Wert aus tempX geholt und damit die Variable innerhalb des Objektes initialisiert.
Das sind pro erstelltem Objekt zwei Konstruktoraufrufe, einmal mit den Standardwerten und dann nochmal mit der eigentlichen Initialisierung. Und genau das will ich verhindern...:(

cya
liquid
Nun, es wäre ja kein Problem, den operator= so zu schreiben dass er genau das macht was dein 2. Konstruktor tut. Denn in deinem Beispiel hast du ja noch eine Initialisierung mehr als in meinem, weil ja object(tempx) ein temporäres Objekt erzeugt.

Und die erste Initialisierung verhinderst du, indem du mit new (oder malloc) nur Speicher anforderst, keinen Konstruktor aufrufst.

Also:
object::operator= (const another_object& X) { blabla }

object* dings = reinterpret_cast<object*>(new char[sizeof(object) * 3]);
dings[0] = temp1;
dings[1] = temp2;
dings[2] = temp3;


und wenn du das Array nicht mehr brauchst:

for(int i = 0; i < 3; i++) dings[i].~object();
delete [] reinterpret_cast<char*>(dings);

liquid
2003-01-03, 18:32:58
Und das geht??? Cool Xmas, du bist mein Held! Ich schreib gleich mal meinen Code um, bis denne! :jump1: