Includeproblem bei mehreren Klassen
-
Guten Tag!
Ich sitze gerade an einer Übung für die Uni, in der ich mehrere Klassen habe, die aufeinander zugreifen. Alle Klassen haben bei mir eine cpp- und eine hpp-Datei, wobei in der cpp-Datei jeweils immer die hpp-Datei includet wird. Folgende Verhältnisse liegen vor:
Graph greift auf Objekte und Funktionen von Vertex und Edge zu.
Vertex greift auf Objekte von Edge zu.
Edge greift auf Objekte von Vertex zu.Nun habe ich das in den hpp-Dateien so gelöst:
Graph.hpp:
#include "edge.hpp"
#include "vertex.hpp"Vertex.hpp:
class edge;Edge.hpp:
class vertex;Wenn ich nun Vertex und Edge zu ner Objektdatei (.o ... ich hoffe, der Name ist richtig) kompiliere, funktioniert das alles super. Wenn ich das gleiche allerdings mit dem Graph machen will, kennt er weder die Vertex-, noch die Edge-Funktionen und -Objekte.
Die Vorlesungsfolien und Beispiele haben mir nicht wirklich geholfen, daher hoffe ich hier auf Hilfe. Was mache ich falsch?
Vielen Dank

-
Grundsätzlich gilt in den Header-Dateien so wenig zu inkludieren wie möglich. Wenn du aber solche Probleme bekommst hilft dir eventuell Forward-Deklaration. Das heißt wenn du in Graph nur Pointer auf die Elemente brauchst, inkludierst du nicht die Header, sondern schreibst dort nur:
class Vertex; class Edge; // ... std::vector<Vertex *> vertexList; std::vector<Edge *> edgeList;Die komplette Definition benötigt der Compiler dann nicht. Geht aber eben nur bei Pointern.
-
Wenn ich das so mache kommen weiterhin Fehler wie
graph.cpp:40: error: `addOutedge' has not been declaredund weitere.

-
Verschiebe die Funktionsrümpfe in die Source-Dateien(.cpp/.cc) und schreib sie nicht in die Header.
-
Hi,
mit forward-Deklarationen ist in dem Augenblick Schluss, in dem Du die konrkete Implementierung der Klasse brauchst - also sobald Du eine Instanz erzeugen oder auf sie zugreifen willst, die Größe einer Instanz (sizeof()) oder statische Elemente der Klasse brauchst.
Da muss dann die "echte" Klassendefinition vorher im Code stehen ... egal, ob via #include oder direkt.
Gruß,
Simon2.
-
jippie, wir haben ein Henne - Ei - Problem

Dabei sollte man sich dann Gedanken über das Klassendesign machen und, ob es wirklich so stimmt, wie man es sich gedacht hat
-
So ein schönes Problem hatte ich auch gerade.
A inkludiert B inkludiert C und so weiter bis sagen wir X. X inkludiert nun Z. An sich kein Problem. Außer nach dem ganzen Durchlauf wird noch Y inkludiert. Denn das muss vor Z inkludiert werden, da Z eine Forward Deklaration sonst durchführt die mit dem eigentlichen Typ in Y eigentlich nichts gemein hat. Schön. Und solch einen Third Party-Kram bekommt man vorgesetzt... grr...
-
Fellhuhn schrieb:
Verschiebe die Funktionsrümpfe in die Source-Dateien(.cpp/.cc) und schreib sie nicht in die Header.
Auch wenn wir es eigentlich so gelernt haben, habe ich es mal ausprobiert. Leider bringt dies genau die gleichen Fehler. Ich habe nun graph.hpp includet, in der eine forwarddeklaration von edge und vertex stattfindet und dann nochmal alle Funktionsrümpfe in die cpp-Datei geschrieben. Habe ich etwas falsch gemacht?
Simon2 schrieb:
Da muss dann die "echte" Klassendefinition vorher im Code stehen ... egal, ob via #include oder direkt.
Jep, ich habe nun alles einmal includet, um Vorwärtsdeklarationen in Edge oder Vertex komme ich aber nicht herum. Frage ist nun, wie ich das richtig anordne. Ich habe alles meiner Meinung nach sinnvolle ausprobiert und es funktioniert nicht.
Vorden schrieb:
jippie, wir haben ein Henne - Ei - Problem

Dabei sollte man sich dann Gedanken über das Klassendesign machen und, ob es wirklich so stimmt, wie man es sich gedacht hatDas Klassendesign ist leider von der Aufgabe her vorgegeben.
So langsam bin ich echt mit meinem Latein am Ende. Das dürfte ja eigentlich kein großes Problem sein, eine "Hauptklasse" auf zwei "Nebenklassen" zugreifen zu lassen, wobei sich diese Nebenklassen gleichzeitig benötigen ... oder?
Vielen Dank schonmal.
-
Touny schrieb:
So langsam bin ich echt mit meinem Latein am Ende. Das dürfte ja eigentlich kein großes Problem sein, eine "Hauptklasse" auf zwei "Nebenklassen" zugreifen zu lassen, wobei sich diese Nebenklassen gleichzeitig benötigen ... oder?
Wie genau ist die Verbindung der Klassen untereinander? Wer "besitzt" was, wer benötigt nur eine Verbindung zum "Navigieren"...
Sofern nur das von dir geschriebene gilt:
Touny schrieb:
Graph greift auf Objekte und Funktionen von Vertex und Edge zu. Vertex greift auf Objekte von Edge zu. Edge greift auf Objekte von Vertex zu.
Gibt es hier keine Besitzverhältnisse. In welcher Verbindung stehen die Objekte? Wer erzeugt diese?
Nehmen wir an, das die Objekte sich nur kennen müssen (Zeiger, Referenzen...),
dann kannst du im Header mit einer reinen Vorwärtsdeklaration arbeiten. In den Headern gehört aber weder ein Funktionsrumpf noch ein Include auf einen der anderen Dateien. Im Source gehört nur die Definition und hier gehören auch die Includes auf die Header hin.cu André
-
Danke Leute für eure Mithilfe. Es war nun nach euren Tipps nur noch mein Fehler, dass ich statt "->" öfter mal ein "." benutzt habe.
Die richtigen includes sind nun:
Edge.hpp #ifndef EDGE_HPP #define EDGE_HPP class vertex; // Klassendefintion #endifVertex.hpp #ifndef VERT_HPP #define VERT_HPP #include "edge.hpp" // Klassendefinition #endifGraphhpp #ifndef GRAPH_HPP #define GRAPH_HPP #include "vertex.hpp" #include "edge.hpp" class edge; // Klassendefinition #endifSo funktioniert es zumindest. Nun muss ich "nur" noch eine Zugriffsverletzung in meinem Programm beheben und schon funktioniert es ;).
Danke.