Objekt-Konstruktor in Memberliste einer anderen Klasse?
-
Guten Abend,
ich versuche einen Objekt-Konstruktor in der Memberliste einer anderen Klasse aufzurufen, leider bekomme ich folgende Fehler:
ClassB.h:11:14: Fehler: »Bar« is not a type
ClassB.h:11:17: Fehler: expected »,« or »...« before »->« tokenHier, mein Quellcode:
ClassA.h
#ifndef ClassA_ #define ClassA_ class ClassA { public: int* Test; public: ClassA(int* inTest) { Test = inTest; } }; #endif
ClassB.h
#ifndef ClassB_ #define ClassB_ #include "ClassC.h" #include "ClassA.h" class ClassB { public: ClassC* Bar; ClassA Foo(Bar->Ptr); // Hier tritt der Fehler auf }; #endif
ClassC.h
#ifndef ClassC_ #define ClassC_ class ClassC { public: int* Ptr; }; #endif
Main.cpp
#include "ClassB.h" int main(int argc, char** argv) { return 0; }
Mit freundlichen Grüßen,
DarkBug
-
.
-
Ah! Jetzt sehe ich!
Was du machen willst, macht aber überhaupt keinen Sinn, denn Bar ist zu dem Zeitpunkt noch überhaupt nicht initialisiert. Was du willst geht zwar (mit C++11, non-static data member initialization), ist aber definitiv nicht was du willst.
Mach lieber das hier:#ifndef ClassB_ #define ClassB_ #include "ClassC.h" #include "ClassA.h" class ClassB { public: ClassC* Bar; ClassA Foo; // Hier tritt kein Fehler auf ClassB(ClassC* barPtr): Bar(barPtr), Foo(Bar->Ptr) {} }; #endif
-
In der Datei ClassB.h in Zeile 11 möchte ich ein Objekt der Klasse ClassA erstellen, das den Namen Foo trägt. Für dieses Objekt soll der in ClassA definierte Konstruktor aufgerufen und der Zeiger Bar, welcher eine Zeile darüber definiert wurde in diesen Konstruktor übergeben werden.
-
DarkBug schrieb:
In der Datei ClassB.h in Zeile 11 möchte ich ein Objekt der Klasse ClassA erstellen, das den Namen Foo trägt. Für dieses Objekt soll der in ClassA definierte Konstruktor aufgerufen und der Zeiger Bar, welcher eine Zeile darüber definiert wurde in diesen Konstruktor übergeben werden.
Aber Bar ist nicht initialisiert! Was will ClassA's Konstruktor damit!?
-
Sorry, das hatte ich jetzt nicht im Beispiel drin. ClassB und auch der Zeiger Bar sind initialisiert. Also wenn der Zeiger später in einer Methode benutzt wird ist er nicht NULL.
-
DarkBug schrieb:
Sorry, das hatte ich jetzt nicht im Beispiel drin. ClassB und auch der Zeiger Bar sind initialisiert. Also wenn der Zeiger später in einer Methode benutzt wird ist er nicht NULL.
Du kannst nicht einen Konstruktor aufrufen wann du willst. Dann müsstest du schon eine Methode in
ClassA
definieren, mit der man nachträglich auf den Zeiger zugreifen kann.
-
Also ist es unmöglich einen Konstruktor außerhalb einer Funktion/Methode aufzurufen?
So funktioniert es aber auch nicht:
ClassB.h
#ifndef ClassB_ #define ClassB_ #include "ClassC.h" #include "ClassA.h" class ClassB { public: ClassC* Bar; ClassA Foo; public: ClassB() { Foo(Bar->Ptr); } }; #endif
Fehlermeldung:
In file included from Main.cpp:1:0:
ClassB.h: In Konstruktor »ClassB::ClassB()«:
ClassB.h:15:3: Fehler: keine passende Funktion für Aufruf von »ClassA::ClassA()«
-
DarkBug schrieb:
Fehlermeldung:
In file included from Main.cpp:1:0:
ClassB.h: In Konstruktor »ClassB::ClassB()«:
ClassB.h:15:3: Fehler: keine passende Funktion für Aufruf von »ClassA::ClassA()«Du darfst Konstruktoren nicht einfach so aufrufen. Die werden nur aufgerufen wenn ein Objekt initialisiert wird, und sie müssen aufgerufen werden - einer von ihnen. Bei dir rufst du gar keinen in der Initialisierungsliste auf, also wird der Default-Ctor genommen - der ja nicht existiert.
Nimm einfach
public: ClassB(): Foo(Bar->Ptr) { }
-
...
Bar
muss dann aber auch initialisiert werden.public: ClassB(): Bar( /* whatever */ ), Foo(Bar->Ptr) { }
-
Funktioniert. Danke!
-
Was mir gestern noch einfiel im Zusammenhang mit Initialisierungslisten: die Reihenfolge der Initialisierung findet in der Reihenfolge statt, in der die Member in der Klassendefinition auftreten. Die 2 Varianten des Standard-c'tors unten sind also äquivalent.
Bar
wird immer vorFoo
initialisiert, weilBar
vorFoo
in der Definition vonClassB
steht (Zeilen 5 u. 6).class ClassB{ public: ClassB(); private: ClassC* Bar; ClassA Foo; }; // 1 ClassB::ClassB() : Bar( /* blabla */ ), Foo( /* blabla */ ) { } // 2 ClassB::ClassB() : Foo( /* blabla */ ), Bar( /* blabla */ ) { }
Ich meine mich zu entsinnen, dass Compiler auch davor warnen, wenn die Reihenfolge vertauscht wird...
Du kannst ja spasseshalberFoo
undBar
in der Klassendefinition vertauschen und Dein Programm elendig crashen sehen...