Kleine Ctor Frage
-
Hallo!
ein paar kleine Fragen zu Konstruktoren:
Wenn ich eine Klasse mit einer Referenz als Member habe:
class A { int& ref; public: A(int i); }dann MUSS ich ref ja in der Initialisierungsliste von A::A() initialisieren.
1. Aber wie sieht das beim Zuweisungsoperator operator= aus? Da existiert das Objekt ja bereits und ref ist für alle Zeiten bereits gebunden. Wie setze ich also ref im operator= ?
2. Wenn A von einer Klasse B erbt, wird dann eigentlich IMMER der Default Ctor von B bei den Konstruktoren auferufen? Also wird zb hier:
A::A(const A& a) { ... }oder hier:
A::A(const A& a) : myVar(a.myVar) { ... }der Default Ctor von B aufgerufen, obwohl ich es nicht explizit schreibe? Muss ich den Aufruf vom, B-Ctor nur schreiben, wenn B keinen Default-Ctor hat?
-
Hi!

ctor schrieb:
2. Wenn A von einer Klasse B erbt, wird dann eigentlich IMMER der Default Ctor von B bei den Konstruktoren auferufen? Also wird zb hier:
A::A(const A& a) { ... }der Default Ctor von B aufgerufen, obwohl ich es nicht explizit schreibe?
Ja und zwar als erstes.
Außer Du gibst einen anderen Konstruktor an, aber ohne geht es (logischerweise) nicht.
-
ctor schrieb:
Wenn ich eine Klasse mit einer Referenz als Member habe:...
dann MUSS ich ref ja in der Initialisierungsliste von A::A() initialisieren.1. Aber wie sieht das beim Zuweisungsoperator operator= aus? Da existiert das Objekt ja bereits und ref ist für alle Zeiten bereits gebunden. Wie setze ich also ref im operator= ?
Garnicht. Eine Zuweisung ist hier nicht möglich.
ctor schrieb:
2. Wenn A von einer Klasse B erbt, wird dann eigentlich IMMER der Default Ctor von B bei den Konstruktoren auferufen? Also wird zb hier:
Der Standard ist: Konstruktoren (mit Ausnahme des Kopierkonstruktors) rufen den Standardkonstruktor der Basisklasse auf (Im Falle des Kopierkonstruktors den Kopierkonstruktor der Basisklasse), sofern du es nicht anders in der Initialisierungsliste angibst:
class Base { Base(); Base(int i); }; class Child : public Base { Child() : Base(1) // Aufruf von Base(int i) statt Base() {} };
-
asc schrieb:
ctor schrieb:
Wenn ich eine Klasse mit einer Referenz als Member habe:...
dann MUSS ich ref ja in der Initialisierungsliste von A::A() initialisieren.1. Aber wie sieht das beim Zuweisungsoperator operator= aus? Da existiert das Objekt ja bereits und ref ist für alle Zeiten bereits gebunden. Wie setze ich also ref im operator= ?
Garnicht. Eine Zuweisung ist hier nicht möglich.
Bedeutet das, dass man Objekte, die eine Referenz als Attribut besitzen, nicht zugewiesen werden können?
int i_1 = 1; int i_2 = 2; A a_1(i_1); A a_2(i_2); a_1 = a_2; // nicht möglich oder a_1.ref == i_1 ?
-
Roger Wilco schrieb:
Bedeutet das, dass man Objekte, die eine Referenz als Attribut besitzen, nicht zugewiesen werden können?
Genau. In Fällen, in denen eine Zuweisung erwünscht ist, sollte man Zeiger benutzen.
-
Danke für die schnellen Antworten!

asc schrieb:
Garnicht. Eine Zuweisung ist hier nicht möglich.
Öhm.. also heißt das, dass wenn eine Klasse eine Referenz als Member hat, ein operator= private gemacht werden muss?
asc schrieb:
Der Standard ist: Konstruktoren (mit Ausnahme des Kopierkonstruktors) rufen den Standardkonstruktor der Basisklasse auf (Im Falle des Kopierkonstruktors den Kopierkonstruktor der Basisklasse), sofern du es nicht anders in der Initialisierungsliste angibst:
Macht dann der automatish erzeugte Kopierkonstruktor im Grunde das hier (A erbt von B):
A::A(const A& rhs) : B(rhs) { }?
-
STL-Container benötigen aber nur den Kopierkonstruktor, oder?
Edit: Auch der Zuweisungsoperator wird benötigt: http://www.cpp-tutor.de/cpp/le18/le18_01.htm#objekte
Das heißt also, dass Klassen, dessen Objekte STL-Containerfähig sein sollen keine Referenzen als Attribute besitzen dürfen. Sonst muss man mit Smart-Pointern arbeiten.
-
Roger Wilco schrieb:
STL-Container benötigen aber nur den Kopierkonstruktor, oder?
Edit: Auch der Zuweisungsoperator wird benötigt: http://www.cpp-tutor.de/cpp/le18/le18_01.htm#objekte
Das heißt also, dass Klassen, dessen Objekte STL-Containerfähig sein sollen keine Referenzen als Attribute besitzen dürfen. Sonst muss man mit Smart-Pointern arbeiten.
imho brauchen sie copy-ctor und std::swap - wenn man std::swap nicht spezialisiert hat, dann auch den zuweisungsoperator - ansonsten nicht...
bb
-
Roger Wilco schrieb:
Bedeutet das, dass man Objekte, die eine Referenz als Attribut besitzen, nicht zugewiesen werden können?
Oh, es gibt schon noch Möglichkeiten, aber nicht auf direkten Weg...
"Wenn sich etwas nicht direkt umsetzen lässt, füge eine weitere Ebene der Indirektion hinzu."
In diesem Falle kann das Handle-Body Idiom eine entsprechende Umsetzung ermöglichen. Wobei dies (wenn nur für dieses Problem angewandt) das Sprichwörtliche schießen von Kanonen auf Spatzen ist.
Folgendes (ungetestet)
// A.h (Inkludeguards etc. weggelassen zur Vereinfachung) #include <memory> // Ich meine hier den TR1-Header class A { public: A(int & ref); A(A const & rhs); A & operator=( A const & rhs); private: struct Impl; std::tr1::shared_ptr<Impl> impl; };#include "A.h" struct A::Impl { Impl(int & value) : ref(ref) {} int & ref; }; A::A(int & ref) : impl(new Impl(ref)) { } A::A(A const & rhs) : impl(new Impl(*rhs.Impl)) { } A & operator=( A const & rhs) { impl = new Impl(*rhs.Impl); // Über Kopierkonstruktor... }
-
Roger Wilco schrieb:
Bedeutet das, dass man Objekte, die eine Referenz als Attribut besitzen, nicht zugewiesen werden können?
Nein, bedeutet es nicht. Es bedeutet rein technisch gesehen nur, dass Objekte, die eine Referenz als Attribut besitzen, nur dann zugewiesen werden können, wenn der Zuweisungsoperator diese Referenz nicht antastet. Dazu ist es nötig, dass er explizit implementiert wird. Ob es semantisch sinnvoll ist, ein Objekt zuweisbar zu machen das eine feste Referenz hat, ist wiederum was anderes.