2010-12-06 3 views
2

J'ai une classe appelée Edge et une classe appelée Vertexclasse d'erreur compilateur C++ n'a pas nommé membre

dans ma classe Edge il y a une référence à une cible appelée Vertex. En Vertex, j'envoie un Edge et j'essaie de changer la cible via le Edge mais j'ai une erreur de compilateur de classe Edge n'a pas de membre nommé target.

mon Edge.h est

#include "Vertex.h" 

class Edge 
{ 
    public: 
    Edge *data; 
    Edge *next; 
    Vertex *target; 

    Edge(); 
    Edge(Edge *x); 
    Edge(Vertex *x); 

    void print(); 

}; 

l'erreur est causée par ce code dans Vertex.cpp

Vertex::Vertex(Edge *x) 
{ 
    name = x->target->name; 
    next = x->target->next; 
    mark = x->target->mark; 
    previous = NULL; 
    next = NULL; 
} 

l'erreur exacte lorsque je tente de compiler Vertex est

g++ -g -I. -c -o Vertex.o Vertex.cpp 
In file included from Vertex.h:3, 
       from Vertex.cpp:3: 
Edge.h:10: error: ISO C++ forbids declaration of ‘Vertex’ with no type 
Edge.h:10: error: expected ‘;’ before ‘*’ token 
Edge.h:14: error: expected ‘)’ before ‘*’ token 
Vertex.cpp: In constructor ‘Vertex::Vertex(Edge*)’: 
Vertex.cpp:26: error: ‘class Edge’ has no member named ‘target’ 
Vertex.cpp:27: error: ‘class Edge’ has no member named ‘target’ 
Vertex.cpp:28: error: ‘class Edge’ has no member named ‘target’ 
+2

Si Edge est déclaré dans Edge.cpp, la déclaration ne sera pas disponible pour Vertex.cpp. – Will

+0

Avez-vous inclus Edge.h dans Vertex.cpp? L'erreur peut être "Edge n'a aucun membre nommé cible car le type n'est pas encore défini" en ayant simplement un coup de poignard. – Seth

+0

Si ces fichiers sont inclus l'un dans l'autre, doivent-ils être dans des en-têtes séparés? Des sons comme Vertex et Edge sont étroitement couplés, vous devriez envisager de les conserver dans le même fichier. – Falmarri

Répondre

1

Si je comprends bien la situation, il semble que vous ayez la déclaration de classe pour Edge dans le .cpp, plutôt que le .h (qu'est-ce que je n l'en-tête alors?). L'erreur dans Vertex se produit parce que lorsque le compilateur recherche la classe Edge, il ne peut pas trouver la déclaration dans l'en-tête Edge - en d'autres termes, il est masqué. Votre déclaration de classe Edge doit figurer dans le fichier d'en-tête et la définition doit figurer dans le fichier .cpp. Notez également que c'est un bon cas de dépendances circulaires, qui peuvent souvent mener à la douleur. Vois si tu ne peux pas les casser. Edit: Merci d'avoir mis l'erreur exacte là-haut, cela a confirmé à peu près toutes nos suppositions. Assurez-vous que les deux classes peuvent se voir - assurez-vous que Vertex inclut l'en-tête d'Edge. Si les classes sont assez petites, vous pourriez vouloir les vider dans un fichier, comme l'a suggéré Falmarri. En outre, n'oubliez pas d'utiliser forward declarations pour résoudre ces types de dépendances circulaires. Vous pouvez transférer des déclarations si vous incluez des pointeurs ou des références à la classe externe dans votre classe, mais cela ne fonctionne pas avec les objets réels (comme Edge edge;) dans votre classe. Je crois que la raison en est que les pointeurs et les références ne sont que des adresses, donc le compilateur n'a pas besoin de connaître les internes, mais pour utiliser un objet réel, vous devez savoir ce qu'il contient.

+0

le Edge.cpp est #include #include "Edge.h" en utilisant namespace std; Edge :: Edge() { data = NULL; suivant = NULL; target = NULL; Edge: Edge (Edge * x) { data = x; target = NULL; suivant = NULL; Edge: Edge (Vertex * x) { target = x; } vide Edge :: print() { cout < nom << endl; } –

+0

J'ai ajouté l'erreur de compilateur exacte de la ligne de commande –

+0

@ John Marcus Merci pour les informations supplémentaires, j'ai mis à jour ma réponse avec une autre façon de travailler à travers ce (déclarations à terme). – Gemini14

0

Mettez la déclaration Edge dans Edge.h et incluez Edge.h dans Vertex.cpp.

0

Semble avoir des dépendances cycliques. Vous pouvez le corriger en ajoutant class avant les noms de classe non déclarés comme class Vertex *target; dans votre déclaration Edge.

1

Toutes les autres réponses expliquent correctement que vous avez un problème avec la dépendance circulaire entre les deux classes et expliquent comment le résoudre.

Ma suggestion est de rendre la classe Vertex non avertie de la classe Edge. Simplement en ajoutant les méthodes getTargetVertex() et getSourceVertex() à la classe edge et en utilisant uniquement le constructeur copy de la classe Vertex.

Bien sûr, cette solution rendra difficile de savoir quelles sont les arêtes qui ciblent un sommet sans vérifier chaque instance de bord dans votre pool/liste d'arêtes disponible.

Questions connexes