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 »->« token

    Hier, 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 vor Foo initialisiert, weil Bar vor Foo in der Definition von ClassB 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 spasseshalber Foo und Bar in der Klassendefinition vertauschen und Dein Programm elendig crashen sehen...


Log in to reply