Problem bei wechselseitig verlinkten Klassen



  • Hallo,

    eigl. habe ich etwas in der Richtung Klasse vom Typ eins enthaelt Zeiger auf KLasse vom Typ 2, die wiederum einen Zeiger auf Klasse vom Typ 1 enthaelt, vor. Als kleine Verstaendnishilfe habe ich hier mal ein Minimalbeispiel:

    Klasse 1:

    #ifndef CLASS1_H_
    #define CLASS1_H_
    
    #include "class2.h"
    
    class class1
    {
     public:
      class1(char *name, class2 *c)
        {
          c2 = c;
          c2->register(this);
          this->name = name;
        }
      ;
    
      void print(void)
      {
        ::std::cout << name << " " << c2->name << endl;
      }
      ;
    
      char *name;
    
      class2 *c2;
    }
    #endif
    

    Klasse 2:

    #ifndef CLASS2_H_
    #define CLASS2_H_
    
    #include "class1.h"
    
    #include <iostream>
    
    class class2
    {
     public:
    
      class2(char *name)
        {
          this->name = name;
        }
      ;
    
      void register(class1 *c1)
      {
        this->c1 = c1;
      }
      ;
    
      void print(void)
      {
        ::std::cout << name << " " << c1->name << endl;
      }
      ;
    
      char *name;
      class1 *c1;
    }
    
    #endif
    

    Und eine Mainmethode:

    #include "class1.h"
    #include "class2.h"
    
    int main(int argc, char *argv)
    {
      class2 *c2 = new class2("Klasse 2");
      class1 *c1 = new class1("Klasse 1", c2);
    
      c1->print();
      c2->print();
    
      delete c1;
      delete c2;
    
      return 0;
    }
    

    Versucht man das zu uebersetzen erhaelt man (ich) :

    g++ main.cc
    class2.h:19: error: expected `)' before ‘*’ token
    class2.h:32: error: ISO C++ forbids declaration of ‘class1’ with no type
    class2.h:32: error: expected ‘;’ before ‘*’ token
    class2.h: In member function ‘void class2::print()’:
    class2.h:27: error: ‘c1’ was not declared in this scope
    class2.h:27: error: ‘endl’ was not declared in this scope
    class1.h: In constructor ‘class1::class1(char*, class2*)’:
    class1.h:12: error: expected unqualified-id before ‘register’
    class1.h:12: error: expected `;' before ‘register’
    class1.h: In member function ‘void class1::print()’:
    class1.h:19: error: ‘endl’ was not declared in this scope
    main.cc: At global scope:
    main.cc:5: error: new types may not be defined in a return type
    main.cc:5: note: (perhaps a semicolon is missing after the definition of ‘class2’)
    main.cc:5: error: two or more data types in declaration of ‘main’
    main.cc:5: error: ‘::main’ must return ‘int’
    make: *** [all] Fehler 1
    

    Erwaehnen sollte icheventuell noch, dass ich den GCC nutze.

    Ich bin in C++ nicht so bewandert, vermute aber, dass es mit dem wechselseitigen Einbinden der Headerdateien zusammenhaengen koennte. class1.h bindet class2.h ein, die wiederum class1.h einbindet...ein endloses Einbinden ist zwar offenbar durch die #ifdef s verhindert, aber anscheinend fehlt gerade deswegen class2.h die Deklaration von class1. Gibt es aber generell ueberhaupt keine Moeglichketi, sowas zu realisieren ( in Java tut es das wohl, daher stammt meine Idee, das Ganze so aufzubauen...). Fuer Anregungen/ Hinweise o Ae. waere ich dankbar:)

    Gruss & Danke
    Michael



  • Um das Problem zu umgehen, würde man grob so vorgehen:

    class class1;
    /* Jetzt gibt es die Klasse class1, Zeiger können angelegt werden,
       auf Member kann aber noch nicht zugegriffen werden. Daher: */
    class class2 { /* Alle Methoden (ohne Rumpf) und Variablen deklarieren. */ }
    class class1 { /* Alles definieren. */ }
    /* Jetzt ist auch class1 vollständig bekannt und es können die
       Methoden von class2 vollständig definiert werden: */
    class2::class2(char *name) {
    /* ... */
    }
    /* ... */
    

    Achja, und auf cout und endl aus dem std namespace wird so zugegriffen:

    std::cout << "..." << std::endl;
    




  • Danke fuer die Hilfe, die Fehlerzahl hat sich nach einigen Aenderungen doch reduziert, es gibt aber nach wie vor welche:

    class2.h:15: error: expected `)' before ‘*’ token
    class2.h: In constructor ‘class1::class1(char*, class2*)’:
    class2.h:41: error: expected unqualified-id before ‘register’
    class2.h:41: error: expected `;' before ‘register’
    class2.h: At global scope:
    class2.h:59: error: expected unqualified-id before ‘register’
    make: *** [all] Fehler 1
    

    Entsprechend oben habe ich das Ganze so umgebaut:

    class2.h:

    #ifndef CLASS2_H_
    #define CLASS2_H_
    
    #include <iostream>
    
    class class1;
    
    class class2
    {
     public:
    
      class2(char *name);
    
      void register(class1 *c1);
    
      void print(void);
    
      char *name;
      class1 *c1;
    }
    ;
    
    class class1
    {
     public:
      class1(char *name, class2 *c);
    
      void print(void);
    
      char *name;
    
      class2 *c2;
    }
    ;
    
    class1::class1(char *name, class2 *c)
    {
      c2 = c;
      c2->register(this);
      this->name = name;
    }
    ;
    
    void class1::print(void)
    {
      ::std::cout << name << " " << c2->name << ::std::endl;
    }
    ;
    
    class2::class2(char *name)
    {
      this->name = name;
    }
    ;
    
    void class2::register(class1 *c1)
    {
      this->c1 = c1;
    }
    ;
    
    void class2::print(void)
    {
      ::std::cout << name << " " << c1->name << ::std::endl;
    }
    ;
    
    #endif
    

    main.cc:

    #include "class2.h"
    
    int main(int argc, char *argv)
    {
      class2 *c2 = new class2("Klasse 2");
      class1 *c1 = new class1("Klasse 1", c2);
    
      c1->print();
      c2->print();
    
      delete c1;
      delete c2;
    
      return 0;
    }
    

    Woran kann das liegen?

    Gruss
    mIchael



  • Was für einen Editor verwendest du (ohne Syntax-Highlighing !!!)?

    register int x = 0; // register ist ein reserviertes Schlüsselwort
    


  • Stimmt ja, hatte ich gar nicht mehr dran gedacht...bin irgendwie zur Zeit etwas verplant...Danke! Nahc Umbenennen laeuft das Ganze wie gewuenscht.


Anmelden zum Antworten