Класс ошибок компилятора c ++ не имеет имени - PullRequest
2 голосов
/ 06 декабря 2010

У меня есть класс с именем Edge и класс с именем Vertex

в моем классе Edge есть ссылка на Вершину с именем target. в Vertex я отправляю Edge и пытаюсь изменить цель через Edge, но у меня ошибка компилятора класса Edge, у которого нет члена с именем target.

мой Edge.h равен

#include "Vertex.h"

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

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

   void print();

};

ошибка вызвана этим кодом в Vertex.cpp

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

точная ошибка при попытке компилировать Vertex:

 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’

Ответы [ 4 ]

1 голос
/ 11 декабря 2010

Все остальные ответы правильно объясняют, что у вас есть проблема с круговой зависимостью между двумя классами, и объясняют, как ее решить.

Я предлагаю сделать класс Vertex неосведомленным о классе Edge.Просто добавив методы getTargetVertex () и getSourceVertex () в класс ребер и используя только конструктор копирования в классе Vertex.

Конечно, это решение затруднит узнать, какие ребрацелевая вершина без проверки каждого экземпляра ребра в вашем доступном пуле / списке ребер.

1 голос
/ 06 декабря 2010

Если я правильно понимаю ситуацию, похоже, у вас есть объявление класса для Edge в .cpp, а не в .h (что тогда в заголовке?).Ошибка в Vertex возникает потому, что когда компилятор ищет класс Edge, он не может найти объявление в заголовке Edge - другими словами, он скрыт.Ваше объявление класса Edge должно быть в заголовочном файле, а определение должно быть в .cpp.Также обратите внимание, что это хороший случай циклических зависимостей, которые часто могут привести к боли.Смотрите, если вы не можете их сломать.

Редактировать: Спасибо за то, что выложили точную ошибку, это в значительной степени подтвердило все наши догадки.Убедитесь, что оба класса могут видеть друг друга - убедитесь, что Vertex включает заголовок Edge.Если классы достаточно малы, вы можете поместить их оба в один файл, как предложил Фалмарри.Также не забудьте использовать форвардные объявления для решения этих типов циклических зависимостей.Вы можете пересылать объявление, если в ваш класс включены указатели или ссылки на внешний класс, но он не работает с реальными объектами (такими как Edge edge;) в вашем классе.Я полагаю, что причина этого в том, что указатели и ссылки являются просто адресами, поэтому компилятору не нужно знать о внутренностях, но чтобы использовать реальный объект, вы должны знать, что внутри.

0 голосов
/ 09 декабря 2010

Кажется, у вас есть циклические зависимости. Вы можете исправить это, добавив class перед необъявленными именами классов, такими как class Vertex *target; в вашем объявлении Edge.

0 голосов
/ 06 декабря 2010

Поместите объявление Edge в Edge.h и включите Edge.h в Vertex.cpp.

...