steckl: C++-Klassen: Beidseitig gerichtete Assoziation

Hi,

ich versuche 2 Klassen zu Programmieren, die gegenseitig Elemente der anderen (oder Referenzen auf die andere) beinhalten können sollen.

Das brauche ich später für die Programmierung eines Pokerspiels, bei dem die Klasse Spiel mehrere Spieler als Attribute enthält, aber die Spieler auch eine Referenz auf das Spiel enthalten sollen, damit sie z.B. sehen können, welche Karten auf dem Tisch liegen.

Ich hab das Ganze mal vereinfacht:

fileA.h:

  
#ifndef CLASS_A_H  
#define CLASS_A_H CLASS_A_H  
  
#include <iostream>  
#include "fileB.h"  
  
using namespace std;  
  
class classA {  
public:  
  classB ab;  
  
  classA(void)  
  {  
   cout << "Konstruktor von A" << endl;  
  }  
};  
  
#endif  

fileB.h:

  
#ifndef CLASS_B_H  
#define CLASS_B_H CLASS_B_H  
  
#include <iostream>  
#include "fileA.h"  
  
using namespace std;  
  
class classB {  
public:  
  classA ba;  
  
  classB(void)  
  {  
   cout << "Konstruktor von B" << endl;  
  }  
};  
  
#endif  

Wenn ich das in einer main-Funktion einbinde und compilieren will kommt folgende Fehlermeldung:
In file included from fileA.h:5,
                 from fileA.cpp:4:
fileB.h:12: Fehler: »classA« bezeichnet keinen Typ

Wenn ich in einer der beiden Dateien das Include der anderen und das Attribut der anderen Klasse weglasse klappt alles.
Wenn ich aus den Attributen Pointer mache (also classA *ba) klappt es ebenfalls nicht.

Gibt es dafür einen Trick? Sowas wie "extern class classA" oder so ähnlich?

Oder geht das grundsätzlich nicht? Was mich aber wundern würde, weil es in der UML ja auch beidseitig gerichtete Assotiationen gibt. Nur finde ich keinen C++ Code dazu.

mfG,
steckl

  1. Hallo,

    Ich kann dir jetzt nicht direkt konkret helfen, aber irgendwie scheint dein Ansatz komisch.

    Ich hätte es so gemacht, dass ich eine Klasse für das Spiel machen würde und eine Klasse für einen Spieler. Da ich kein C++ kann hier ein wenig Pseudocode:

    class Game {  
     private array players;  
     public method addPlayer(player) { this.players.push(player) };  
     public method start() {};  
    }  
      
    class Player {  
     private object game;  
     private constructor Player(game) { this.game = game; }  
    }  
      
    game = new Game();  
      
    player1 = new Player(game);  
    player2 = new Player(game);  
    player3 = new Player(game);  
      
    game.addPlayer(player1);  
    game.addPlayer(player2)  
    game.addPlayer(player3);  
      
    game.start();
    

    Dann hast du deine Beziehungen wunderbar abgebildet und die Spieler können auf das Spiel zugreifen und das Spiel weiß welche Spieler aktuell mitspielen. Ich weiß nicht ob ich deine Frage richtig verstanden habe, aber so würde ich an die Sache herangehen. Wenn ich ganz falsch liege dann freue ich mich schon auf eine Erklärung wie man es richig[er] macht :D

    Jeena

    1. Hi,

      Ich kann dir jetzt nicht direkt konkret helfen, aber irgendwie scheint dein Ansatz komisch.

      Er ist genau wie deiner. Vielleicht ist es nur nicht so rüber gekommen, weil ich ein einfacheres Code-Beispiel gewählt, da es hier schon nicht klappt.

      Ich hätte es so gemacht, dass ich eine Klasse für das Spiel machen würde und eine Klasse für einen Spieler. Da ich kein C++ kann hier ein wenig Pseudocode:

      class Game {

      private array players;
      public method addPlayer(player) { this.players.push(player) };
      public method start() {};
      }

      class Player {
      private object game;
      private constructor Player(game) { this.game = game; }
      }

        
      Genau so hätte ich es auch gemacht, nur muss ich statt "private object game" den Datentyp (bzw. Klassenname) von game angeben, in diesem Fall wäre das Game.  
      Die Deklaration der Klassen Game und Player möchte ich in 2 unterschiedliche Module packen (wie in meinem Beispiel classA und classB).  
      Wenn sich die beiden Module jetzt gegenseitig einbinden sollen sagt der Compiler, dass der Datentyp nicht bekannt ist.  
        
      
      > Dann hast du deine Beziehungen wunderbar abgebildet und die Spieler können auf das Spiel zugreifen und das Spiel weiß welche Spieler aktuell mitspielen.  
        
      Ja, genau.  
        
      
      > Ich weiß nicht ob ich deine Frage richtig verstanden habe, aber so würde ich an die Sache herangehen. Wenn ich ganz falsch liege dann freue ich mich schon auf eine Erklärung wie man es richig[er] macht :D  
        
      Du hast es mir so erklärt, wie ich es auch machen wollte, aber nicht in C++ umsetzen kann.  
        
      mfG,  
      steckl
      
  2. hi!

    Das Stichwort heisst "forward declaration". Mehr dazu: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.11

    bye, Frank!

    --
    Never argue with an idiot. He will lower you to his level and then
    beat you with experience.
    1. Hi,

      Das Stichwort heisst "forward declaration". Mehr dazu: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.11

      Super, vielen Dank!
      Ich muss einfach nur "class classA;", bzw. "class classB;" in die entsprechenden Dateien einfügen. :-)

      mfG,
      steckl