Zwei Klassen verbinden?
-
Hey,
Ich habe eine wahrscheinlich recht blöde Frage.
Also wie kann ich 2 Klassen verbinden?
Ich will nicht vererben sondern ich mochte das beide Klassen auf die jeweiligen Methoden der anderen zugreifen können.
Es geht darum das KlasseA die Oberfläche ist und KlasseB die Steuerung.
Diese sollte ja rein von der Logik her bidirektional verbunden sein.In meinem Porgramm läuft das so:
In der Main wird ein Objekt der GUI erstellt und in der GUI dann ein Objekt der
Steuerung. Somit kennt die GUI schon mal die Steuerung.
Aber wie kann ich der Steuerung jetzt sagen was die gui ist?
Also welches Objekt. Ich habe versucht es im Konstruktor zu übergeben,
was aber leider überhaupt nicht funktioniert hat. (Die Klasse wurde nicht als
Datentyp anerkannt)Könnt ihr mir helfen?
-
gosch00 schrieb:
Also wie kann ich 2 Klassen verbinden?
Indem du jede Klasse jeweils Methoden der anderen aufrufen lässt.
gosch00 schrieb:
Ich habe versucht es im Konstruktor zu übergeben,
was aber leider überhaupt nicht funktioniert hat. (Die Klasse wurde nicht als
Datentyp anerkannt)Kannst du diesbezüglich etwas konkreter werden? Ein kurzer, problembezogener Code und die exakte Fehlermeldung wären hilfreich. Der entsprechende Header ist in der .cpp-Datei schon eingebunden, oder?
-
Erstmal code:
#include <iostream> #include "KlasseB.h" using namespace std; class KlasseA { public: KlasseA(); virtual ~KlasseA(); private: KlasseB* b; };
#include "KlasseA.h" KlasseA::KlasseA() { cout << "Klasse A erstellt!" << endl; b = new KlasseB(this); } KlasseA::~KlasseA() { cout << "Klasse A zerstört!" << endl; }
#include <iostream> #include "KlasseA.h" using namespace std; class KlasseB { public: KlasseB(KlasseA p); virtual ~KlasseB(); private: KlassA* A; };
#include "KlasseB.h" KlasseB::KlasseB(KlasseA p) { cout << "Klasse B erstellt!" << endl; A=p; } KlasseB::~KlasseB() { cout << "Klasse B zerstört!" << endl; }
So soll das im groben Funktionieren.
Ist das Problem vielleicht das das ich Klasse B in Klasse A erstelle?
Und dann übergeben will?
Lasse ich die übergabe nämlich weg und lasse nur die GUI die Steuerung kennen funktioniert es.
-
Diese Frage wird ca. jeden Tag gestellt. Darum fühle ich mich einmal wieder genötigt dich auf diesen Artikel hier hinzuweisen:
http://www.drakon.ch/?id=&offset=3&mobile=0&show_entry=77Kurz:
Das, was du da machst ergibt zyklische Abhängigkeiten und muss mit Vorwärtsdeklarationen umgangen werden (näheres dazu im Artikel).btw:
using namespace std;
Das ist im Header nicht gut. Überleg mal was passiert, wenn jemand anderst deinen Header einbindet und zufälligerweise z.B eine eigene Klasse string hat. (gibt einen Namenskonflikt mit std::string..)
-
Da gibts mehrere Probleme bzw. Unschönheiten.
1) Du kannst nicht zwei Dateien sich gegenseitig einbinden lassen. Das würde zu einer Endlosrekursion führen. Deshalb solltest du mit Vorwärtsdeklarationen arbeiten:
// KlasseA.h class B; // <- Vorwärtsdeklaration class A { // ... };
// KlasseB.h class A; class B { // ... };
2) Gibt es einen Grund, warum du eine Kopie statt eines Zeigers oder einer Referenz übergibst? Warum nicht eines davon (wenn möglich mit
const
):KlasseB(KlasseA& p); KlasseB(KlasseA* p);
3) Benutze NIE NIE NIE
using namespace
in Headerdateien. Dadurch wird nämlich der ganze Namensraum für alle inkludierenden Dateien ausgeleert. Auf diese Weise sind Namensräume äusserst sinnlos.4) Benutze für Konstruktoren Initialisierungslisten statt Zuweisungen. Folgendes
KlasseB::KlasseB(KlasseA* p) { A = p; }
wird zu
KlasseB::KlasseB(KlasseA* p) : A(p) { }
5) Ich sehe keinen Grund, warum die Destruktoren virtuell sind. Falls du die Klassen nicht polymorph benutzt, verzichte auf
virtual
. Nur weil du sowas später in Betracht ziehen könntest, musst du das noch nicht jetzt tun.Selbst wenn andere Klassen von
KlasseA
bzw.KlasseB
erben, ist das noch kein Grund für einen virtuellen Destruktor. Du brauchst virtuelle Funktionen wirklich nur, wenn du Objekte abgeleiteter Klassen über einen Zeiger oder eine Referenz auf die Basisklasse ansprechen willst.6) Halte Abhängigkeiten klein. Inkludiere Headerdateien nur, falls wirklich nötig, und tu das so spät wie möglich.
<iostream>
muss erst in den .cpp-Dateien bekannt sein, also reicht ein#include
dort.