006
12.08.2005, 17:11 Uhr
virtual
Sexiest Bit alive (Operator)
|
Zitat von ~Reiko: |
2) X zeta(X())
Der Prototyp wäre also X(X& arg); der Copy-ctor, ok.
|
Fast, der Prototyp sollte besser lauten
const ist das Versprechen, daß arg im ctor nicht verändert wird. Das ist etwas anderes als final in Java: in Java bedeutet final ja erstmal nur, daß die Referenz des Objektes nicht geändert werden darf, das const geht einen Schritt weiter und drückt aus, daß der Inhalt des Objekts nicht verändert werden darf. Wenn Du nun
schreiben würdest, signalisierst Du damit dem Compiler, daß es möglich wäre, daß arg nach dem Aufruf des ctors einen anderen Inhalt haben könnte. Dies kann in bestimmten Situationen zu Problemen führen. Daher gewöhne dir frühzeitig an, bei Parametern, die nicht verändert werden, ein const davor zu setzen. Bei einem copy ctor ist dies im überwiegenden Teil der Fälle so.
Zitat: |
Eine Frage war noch unbeantwortet bzw. es ging aus deinen Ausführungen nicht hervor, ob jedem ctor-Aufruf die physikalische Objekt-Erstellung vorangeht bzw. ob jeder explizite ctor-Aufruf bedeutet, dass ein Objekt erzeugt wird?
C++: |
int main(){ X zeta(X()) // in diesem Fall wird doch der ein Objekt durch X() erzeugt, aber doch nur, // weil es sich dabei um dem copy-ctor handelt <= verlangt Objekt-Referenz
X(); // Wie siehts aber hier aus? Anonymes Objekt oder einfacher Konstruktor ohne // Objekterzeugung?
|
Grund der Frage: Viele schreiben umkorrekterweise, dass ein Konstruktor ein Objekt erstellt, dabei wird das Objekt (Speicherplatzreservierung) ja vor dem ctor durchgeführt, sodass der ctor nur ein Initialisierer ist. Die andere Seite wäre, dass ein Konstruktoraufruf immer auch eine vorangehende Objekterstellung signalisiert.
|
Du hast zwar recht, daß die Objekterstellung in zwei schritten Stattfindet, nämlich erst bereitstellung des Speichers und anschliessend die Initialisierung durch den ctor. Allerdings fallen diese Beiden dinge in der Regel zusammen. Es gibt zwar einige advanced features, wie man diese beiden Schritte trennen kann (Stichworte: "placement new" und "Allocatoren"), aber vereinfachend kann man sich vorstellen, daß beide Schritte zunächst untrennbar miteinander verbunden sind. Der Ausdruck "X();" erzeugt somit ein Objekt auf dem Stack und ruft den ctor auf. Da du keine Zuweisung an eine Variable machst bzw. dieses Objekt nicht direkt verwendest (wie in der Zeile darüber), ist das Objekt zwar da, aber nicht weiter referenzierbar.
Zitat: |
Wie siets denn mit Konstruktorenverkettung in C++ aus, also der Aufruf 2er oder mehrer Konstruktoren derselben Klasse für ein einziges Objekt, wie man es aus Java kennt? Gibts das auch in C++?
|
Mir fällt der Fachbegriff nicht ein, aber ich glaube du meinst sowas:
Code: |
public class JavaClass { public JavaClass(int x) { this(x, 0); // Meinst Du das? } public JavaClass(int x, int y) { ... } }
|
Meinst du sowas? - Das geht nicht in C++. Man kann sich zwr behelfen mit
C++: |
class CppClass { public:
CppClass(int x) { init(x); } CppClass(int x, int y) { init(x,y); }
void init(int x, int y=0) { } };
|
Aber das ist nur eine krücke, weil insbes. wenn man referenzen in C++ Klassen hat, geht dieser "Trick" nicht mehr: man muß nämlich Referenzen direkt über Initialisiererlisten im ctor initialisieren. -- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) |