Gegenseitiges Aufrufen von Memberfunktionen zweier Klassen



  • cooky451 schrieb:

    Du versuchst eine nicht statische Methode aufzurufen, ohne dabei ein konkretes Objekt anzugeben. Das kann nicht funktionieren. Entweder du machst die Methode statisch, oder du gibst der Funktion ein Objekt mit.

    ---
    Du versuchst Folgendes:

    class A
    {
    public:
      void foo()
      {
      }
    };
    
    void bar()
    {
      A::foo(); // hier knallt es
    }
    

    Mache foo() static oder gebe bar ein Objekt der Klasse A.
    ---
    Oder du versuchst:

    class A
    {
      int i;
    public:
      static void foo()
      {
        i = 5; // hier knallt es
      }
    };
    

    Dann solltest du dein Design noch mal überdenken, falls du nichts ändern kannst, solltest du i static machen. (Aufpassen bei Multithreading mit statischen Membern.)

    Ok aber wie maches ich es dann bei den Memberfunktionen der eigenen Klasse? Zeiger auf sich selbst? Denn eigentlich existiert ja ein Objekt nur wird dies eben in einer übergeordneten Klasse erzeugt.



  • Ich verstehe deine Frage nicht so ganz, aber mal in's Blaue geraten:

    class A
    {
      int i;
      static void foo(A& a)
      {
        a.i = 5;
      }
    };
    
    class C
    {
      A a;
      C()
      {
        A::foo(a);
      }
    }
    

    Wobei das eigentlich völlig sinnfrei ist, da kann man auch einfach das static vor foo() wegnehmen. (Oder halt einen Konstruktor für A bauen. 🙄 )Am besten du postest mal ein kleines Minimalbeispiel mit deinem Code (kann auch Pseudocode wie hier sein).



  • Header Überklasse :

    Class1 A;
    Class2 B;
    

    Header Class A

    class Class2;  //Vorabdeklaration
    
    class Class1
    {
    public:
    Class1(void); // Konstruktor
    
    int Test_Func1(Class2 * p2);
    int Test_Func2(void);
    private:
    int Test_Func3(void);
    Class2 * mpClass2;
    }
    

    Header Class B

    class Class1;  //Vorabdeklaration
    
    class Class2
    {
    public:
    Class1(void); // Konstruktor
    
    int Test_Func1(Class1 * p1);
    int Test_Func2(void);
    private:
    int Test_Func3(void);
    Class1 * mpClass1;
    }
    

    cpp der Überklasse:

    B.Test_Func1(&A);
    A.Test_Func1(&B)
    

    cpp der Klasse, die Probleme bereitet:

    int
    Class2::Test_Func1(Class1 * p1)
    {
    mpClass1 = p1;
    //Hier kann ich ohne Probleme alles ausfürhen
    }
    int
    Class2::Test_Func2(void)
    {
    //hier kracht es dann mit oben gennanter Fehlermeldung unabhängig welche Funktionen ich aufrufe
    }
    

    ich hoffe das Beispiel bringt ein wenig Licht ins dunkle 🙂 Könnte es etwas mit den Headern und den Vorabdeklarationen zu tun haben die ich "über Kreuz" einbinden muss?

    ach und vielen dank für die schnelle Hilfe 👍



  • da fehlt ein "int" vor der entsprechenden Funktion (auch wenn du den Fehler vll nur hier im Forum gemacht hast)

    greetz KN4CK3R



  • Innerhalb der cpp von Class1 kann ich ohne Probleme über

    mpClass2->
    

    auf jede gewollte Funktion von Class2 zugreifen nur umgekehrt funktioniert es nicht.



  • Zeig doch mal ein konkretes Beispiel für Zeile 10. (Oder besser: Poste ein vollständig kompilierbares, bzw. diesen Fehler verursachendes Beispiel, möglichst in einer Quelltextdatei. Dann sieht man vermutlich sofort wo es hakt.)



  • wuddy45 schrieb:

    ich hoffe das Beispiel bringt ein wenig Licht ins dunkle 🙂 Könnte es etwas mit den Headern und den Vorabdeklarationen zu tun haben die ich "über Kreuz" einbinden muss?

    Was Du wo wie inkludierst, hast Du ja gar nicht gezeigt. Ich denke, da liegt der Hund begraben.



  • haupt_class.h:

    #ifndef HAUPT_CLASS_H_FIRST
    #define HAUPT_CLASS_H_FIRST
    
    #ifndef CLASS1_H_FIRST
    #include "class1.h"
    #endif
    
    #ifndef CLASS2_H_FIRST
    #include "class2.h"
    #endif
    
    class Haupt
    {
    public:
    
        Haupt(void);
        ~Haupt(void);
    
    	void Main(void);
    
    private:
    
        int Init(void);	
    
    	Class1 mA;
        Class2 mB;
    
    };
    #endif
    

    haupt_class.cpp:

    #ifndef _HAUPT_H_FIRST
    #include "haupt.h"
    #endif
    
    void UCCM::Main(void)
    {
      mB.Init(&mA);
      mA.Init(&mB);
    
    }
    

    class1.h:

    #ifndef CLASS1_H_FIRST
    #define CLASS1_H_FIRST
    
    class Class2;	//Vorabdeklaration
    
    class Class1
    {
    public:
    
        Class1(void);
    
        ~Class1(void); 
    
            int Init(Class2 * p2);
    		int funct1(void);
    private:
    
        Class2 * mpClass2;
    
    };
    #endif
    

    class1.cpp:

    #ifndef CLASS1_H_FIRST
    #include "class1.h"
    #endif
    
    #ifndef CLASS2_H_FIRST
    #include "lcass2.h"
    #endif
    
    #ifndef _HAUPT_H_FIRST
    #include "haupt.h"
    #endif
    
    int Class1::Init(Class2 * p2)
    {
    
    mpClass2 = p2;
    return 0;
    }
    
    int Class1::funct1(void)
    {
    
    mpClass2->funct2(); // ohne Fehler
    return 0;
    }
    

    class2.h:

    #ifndef CLASS2_H_FIRST
    #define CLASS2_H_FIRST
    
    class Class1;	//Vorabdeklaration
    
    #ifndef CLASS1_H_FIRST
    #include "class1.h"
    #endif
    
    class Class2
    {
    public:
    
        Class2(void);
        ~Class2(void);
    	    int Init(Class1 * p1);
    		int funct2(void);
    		int funct3(void);
    
    private:	
    
    Class1 * mpClass1;	
    
    };
    #endif
    

    class2.cpp:

    #ifndef CLASS1_H_FIRST
    #include "class1.h"
    #endif
    #ifndef ClASS2_H_FIRST
    #include "class2.h"
    #endif
    
    int Class2::Init(Class1 * p1)
    {
    
    mpClass1 = p1;
    return 0;
    }
    
    int Class2::funct2(void)
    {
    
    mpClass1->funct1(); //oben gennanter Fehler
    return 0;
    }
    
    int Class2::funct3(void)
    {
    
    funct2();   //oben gennanter Fehler
    return 0;
    }
    


  • Auweia! Include-Guards gehören in den jeweiligen Header!

    haupt_class.h:

    #ifndef HAUPT_CLASS_H_INCLUDED
    #define HAUPT_CLASS_H_INCLUDED
    
    #include "class1.h"
    #include "class2.h"
    
    class Haupt
    {
    public:
    
        Haupt();
        ~Haupt(); // <-- Wozu eigentlich ?!
    
        void Main();
    
    private:
    
        int Init();
    
        Class1 mA;
        Class2 mB;
    
    };
    
    #endif
    

    haupt_class.cpp:

    #include "haupt_class.h"
    
    void Haupt::Main()
    {
      mB.Init(&mA);
      mA.Init(&mB);
    
    }
    ...
    

    class1.h:

    #ifndef CLASS1_H_INCLUDED
    #define CLASS1_H_INCLUDED
    
    class Class2;	//Vorabdeklaration
    
    class Class1
    {
    public:
        Class1();
        ~Class1(); // <-- Wozu eigentlich?
        int Init(Class2 * p2);
        int funct1();
    private:
        Class2 * mpClass2;
    };
    
    #endif
    

    class1.cpp:

    #include "class1.h"
    #include "class2.h"
    
    int Class1::Init(Class2 * p2)
    {
    mpClass2 = p2;
    }
    
    int Class1::funct1()
    {
    mpClass2->funct2();
    }
    ...
    

    class2.h:

    #ifndef CLASS2_H_INCLUDED
    #define CLASS2_H_INCLUDED
    
    class Class1;	//Vorabdeklaration
    
    class Class2
    {
    public:
        Class2();
        ~Class2();
        int Init(Class1 * p1);
        int funct2();
        int funct3();
    private:	
    Class1 * mpClass1;	
    };
    
    #endif
    

    class2.cpp:

    #include "class1.h"
    #include "class2.h"
    
    int Class2::Init(Class1 * p1)
    {
      mpClass1 = p1;
    }
    
    int Class2::funct2()
    {
      mpClass1->funct1();
    }
    
    int Class2::funct3()
    {
      funct2();
    }
    ...
    

    Da, wo ich "..." geschrieben habe, müsste man noch Konstruktor, Destruktor definieren. Ich frage mich aber, wozu die Destruktoren da sind. Wenn Du selbst geschriebene Destruktoren brauchst, brauchst Du wahrscheinlich auch eigene Kopier- und Zuweisungsoperatoren.

    Es fehlten übrigens überall die Semikolons am Ende der Klassendefinitionen. Bitte das nächste mal nur copy&paste und kein aus'm-Kopf-runtertippen. Die Fehler, die du dabei einbaust, helfen keinem. Es ist Deine Aufgabe, hier ein vernünftiges Beispiel reinzustellen, welches Du in seiner kompletten Form getestet hast. Du musst also den Code stark vereinfachen und dann selbst nochmal testen.

    Wenn eine Funktion keine Parameter bekommt, solltest Du das "void" weglassen. Es ist nicht falsch. Aber das macht sonst keiner in C++, da überflüssig. In C (altem) ist das was anderes.



  • Leider komme ich aus der reinen C-Welt und hab nicht so viel Erfahrung mit C++ daher bitte ich um Verständnis. Auch was die Fehler innerhalt des Codes angeht werde ich mich zukünftig bemühen diese fehlerfrei zu posten. Mir war es allerdings wichtig den generellen Sachverhalt kurz darzustellen.



  • wuddy45 schrieb:

    Leider komme ich aus der reinen C-Welt

    In C werden die Includeguards nicht anders verwendet.



  • manni66 schrieb:

    wuddy45 schrieb:

    Leider komme ich aus der reinen C-Welt

    In C werden die Includeguards nicht anders verwendet.

    Schon klar, das war auch eher auf die Sache mit void bezogen.


Anmelden zum Antworten