Problem beim Erben
-
Hallo,
Ich habe ein Problem, wenn ich versuche von einer Klasse zu erben:
Meine Kindklasse ruft im Konstruktor den Konstruktor der Basisklasse auf, um so einige Werte zu initialisieren, jedoch werden diese Werte in der Erbenden Klasse nicht "aktualisiert"???
Etwa so:
#include <iostream> class a { public: a() {} a(int num) { m_num = num; std::cout << "A: " << m_num << std::endl } protected: int m_num; }; class b : public a { public: b() {} b(int num) { a::a(num); std::cout << "B: " << m_num << std::endl; } }; int main() { b B(7); return 0; }Ausgabe:
A: 7
B: Irgendetwas (Manchmal 1, manchmal 16...)
-
Hallo,
Du musst hier Initialisierungslisten verwenden.
#include <iostream> class a { public: a() {} a(int num) : m_num(num) { std::cout << "A: " << m_num << std::endl } protected: int m_num; }; class b : public a { public: b() {} b(int num) : a(num) { std::cout << "B: " << m_num << std::endl; } }; int main() { b B(7); return 0; }
-
Dankeschön!
Weshalb ist das denn so?
-
Erst mal eine Frage. Hat deine Variante überhaupt compiliert? Bei mir geht das nämlich nicht.
Falls das doch geht, wird hier wahrscheinlich nur ein temporäres Objekt vom Typ a im Konstruktor von b angelegt. Dieses hat natürlich keinen Einfluss auf das b-Objekt selbst.
An sich kann man Konstruktoren nämlich so nicht direkt aufrufen sondern nur in der Initialisierungsliste einer abgeleiteten Klasse.
-
Samyboy schrieb:
class a { public: a() {} a(int num) { m_num = num; std::cout << "A: " << m_num << std::endl } protected: int m_num; };Ist der Default-Konstruktor sinnvoll? Er macht ja nichts und erlaubt es, eigentlich uninitialisierte Objekte vom Typ 'a' zu erzeugen.
class b : public a { public: b() {} b(int num) { a::a(num); std::cout << "B: " << m_num << std::endl; } };Dieser Konstruktor ruft automatisch (compiler-generiert) Deinen Default-Konstruktor von A auf, der ja nichts macht. Das passiert quasi vor der {-Klammer. Dann erstellst Du temporär ein weiteres A-Objekt (mit
a::a(num);), welches gleich darauf wieder zerstört wird mit dem Semikolon. Bei einer abstrakten Basisklasse wäre das sofort aufgefallen, weil eine abstrakte Klasse nie der dynamische Typ eines Objektes sein kann.Folgendes noch zum Überlegen:
- Ist das vielleicht ein Missbrauch der Vererbung?
- Sollten die Konstruktoren, die einenintnehmen,explicitsein?
-
Braunstein schrieb:
Erst mal eine Frage. Hat deine Variante überhaupt compiliert? Bei mir geht das nämlich nicht.
Falls das doch geht, wird hier wahrscheinlich nur ein temporäres Objekt vom Typ a im Konstruktor von b angelegt. Dieses hat natürlich keinen Einfluss auf das b-Objekt selbst.
An sich kann man Konstruktoren nämlich so nicht direkt aufrufen sondern nur in der Initialisierungsliste einer abgeleiteten Klasse.Joa, der Code hat bei mir kompiliert

Dankeschön für die Erläuterung!
-
krümelkacker schrieb:
Samyboy schrieb:
class a { public: a() {} a(int num) { m_num = num; std::cout << "A: " << m_num << std::endl } protected: int m_num; };Ist der Default-Konstruktor sinnvoll? Er macht ja nichts und erlaubt es, eigentlich uninitialisierte Objekte vom Typ 'a' zu erzeugen.
class b : public a { public: b() {} b(int num) { a::a(num); std::cout << "B: " << m_num << std::endl; } };Dieser Konstruktor ruft automatisch (compiler-generiert) Deinen Default-Konstruktor von A auf, der ja nichts macht. Das passiert quasi vor der {-Klammer. Dann erstellst Du temporär ein weiteres A-Objekt (mit
a::a(num);), welches gleich darauf wieder zerstört wird mit dem Semikolon. Bei einer abstrakten Basisklasse wäre das sofort aufgefallen, weil eine abstrakte Klasse nie der dynamische Typ eines Objektes sein kann.Folgendes noch zum Überlegen:
- Ist das vielleicht ein Missbrauch der Vererbung?
- Sollten die Konstruktoren, die einenintnehmen,explicitsein?Hallo,
Danke erstmal für deine Antwort!
Also das oben macht gar keinen Sinn, du hast Recht :D.
Und "explicit" hab ich noch nie gehört, werd mal Googeln und mich weiterbilden xD
-
Nochwas zum Überlegen.
Sollte der Defaultkonstruktor nicht die Membervariablen mit sinnvollen Werten belegen sofern diese nicht selbst einen Konstruktor haben?
-
Braunstein schrieb:
Nochwas zum Überlegen.
Sollte der Defaultkonstruktor nicht die Membervariablen mit sinnvollen Werten belegen sofern diese nicht selbst einen Konstruktor haben?Und was zum davor-überlegen: macht es überhaupt immer Sinn, einen Default-Ctor zu haben?
-
Das weiß man erst wenn man die Anwendung kennt. Natürlich würde es hier auch ein default Parameter tun.