Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » bidirektionale Objektreferenzen mit C++

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
17.11.2005, 12:35 Uhr
~maxpower24
Gast


Kurzform der Frage: Wie kriegt man es hin, dass sich 2 Klassen gegenseitig kennen?? Ich hab hier Probleme mit den include-Dateien.

Hallo,

ich habe noch nicht sehr viel Erfahrung mit C++ (aber mit OO-Programmierung) und hab daher eine Frage zu folgendem Problem:

Ich habe eine Klasse A (Dateien A.h und A.cpp) und eine Klasse B (Dateien B.h und B.cpp). Die Klasse A soll eine Membervariable vom Typ der Klasse B haben und die Klasse B soll wiederum eine Membervariable vom Typ der Klasse A haben - somit haben wir eine bidirektionale Hat-Beziehung.

Bei der Implementierung dessen, ist es ja nun erforderlich, dass die Datei A.h die Datei B.h inkludiert (damit sie den Typ B kennt). Gleichsam ist es auch erforderlich, dass die Datei B.h die A.h inkludiert, damit sie den Typ A kennt. Die *.cpp-Dateien inkludieren dann nur noch die für sie relevante *.h-Datei.

Hier spielt irgendwie mein Linker verrückt - offensichtlich handelt es sich um ein Problem der Sorte "die katze beißt sich in den Schwanz"...Ich hab dann mal versucht, die *.h-Dateien mit den folgenden Prä-Prozessor-Direktiven zu versehen:

#ifndef _A_ //...für Klasse A
#define _A_
......//includes und Klassendeklaration

#endif

Der effekt war, dass nun beim Compilieren, die Typen nicht mehr erkannt wurden, weil offensichtlich, die *h-Dateien nur 1mal im Projekt inkludiert wurden (Tatsächlich gibt es ja aber im Projekt 2 #include "A.h" - Anweisungen, nämlich einmal in A.cpp und einmal in B.h).

Kurzum:
******
Wie kann ich dieses Problem lösen?? Wie sind solche bidirektionalen Objektreferenzen in C++ realisierbar???

Danke für jeden Hinweis.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.11.2005, 12:43 Uhr
Tommix



Hallo,

Zitat von ~maxpower24:
...Die Klasse A soll eine Membervariable vom Typ der Klasse B haben und die Klasse B soll wiederum eine Membervariable vom Typ der Klasse A haben...

Dieser Member (A in B) hätte dann ja wieder einen Member B, der einen Member A hat, der einen Member B hat ... Will sagen, das geht so nicht. Du kannst einer der Klassen, z.B. A, einen Member vom Typ Zeiger auf B verpassen. Dann kannst Du den Include im Header in die CPP-Datei verschieben und durch eine Vorwärtsdeklaration ersetzen:

C++:
class B;

class A {
//...
B* pB;
//...
}



Gruß, Tommix

Dieser Post wurde am 17.11.2005 um 12:44 Uhr von Tommix editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.11.2005, 12:44 Uhr
0xdeadbeef
Gott
(Operator)


Direkt als Membervariable geht das nicht, Objekte sind in C++ ja keine Referenztypen wie z.B. in Java. Mindestens eine der beiden Klassen muss die andere als Zeiger halten. (Bei einer flachen Einbettung enthielte im Endeffekt Datentyp A, der ein Objekt vom Typ B enthält, damit implizit sich selbst. Mit anderen Worten, seine Größe wäre unendlich)

Das mit den Zeigern sieht dann so aus:

C++:
// foo.h
#ifndef FOO_H
#define FOO_H

#include "bar.h"

class foo {
private:
  bar b;
};

#endif

// bar.h

#ifndef BAR_H
#define BAR_H

class foo;

class bar {
private;
  foo *f;
};

#endif


Wobei dann bar::f im Konstruktor von bar initialisiert werden sollte und im Weiteren wie ein Pointer benutzt werden muss (im Wesentlichen -> statt .)
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
17.11.2005, 14:41 Uhr
ao

(Operator)


Eine einseitige Hat-Beziehung (B als Member von A) würde ja noch gehen, damit wird ein starkes Eigentumsverhältnis ausgedrückt: "B ist Teil von A". Sowas wie

C++:
class Gehirn { };

class Mensch
{
    Gehirn meinGehirn;
};



Wenn aber B Eigentum oder Teil von A ist, kann nicht A nicht umgekehrt Eigentum von B sein. Dass kreuzweise Member in C++ nicht gehen, entspricht also ganz gut der Wirklichkeit. Wenn du abbilden willst, dass B seinen Eigentümer kennt, verwende innerhalb von B eine Referenz oder einen Pointer auf A, wie die anderen schon sagten:


C++:
class Mensch;
class Gehirn
{
    class Mensch & meinMensch;
};



In diesem Fall muss die Referenz meinMensch schon bei der Konstruktion von Gehirn initialisiert werden:

C++:
Gehirn::Gehirn (Mensch & m) : meinMensch (m) {}
Mensch::Mensch () : meinGehirn (*this) {}


aber wenn man mal drüber nachdenkt: Auch das macht Sinn. Außerdem wäre sinnvoll, das Gehirn so zu definieren:

C++:
class Gehirn
{
    class Mensch & const meinMensch;
};


, es sei denn, das Gehirn soll später mal transplantiert werden.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: