В C ++ что-то не так, в том числе и таким образом? - PullRequest
0 голосов
/ 15 октября 2011

В моей программе есть классы для Vertex's Edges and Faces, которые я надеюсь использовать для моделирования фигур.До этого мой класс Edge включал мой файл "vertex.h", а мой класс Face включал мой файл Edge.h.В классе Face я объявил некоторые переменные типа ребер, а в классе Edge я объявил некоторые переменные типа вершины.Все работает.Моя проблема заключается в том, что во время реализации я понял, что хочу, чтобы ребра знали о гранях, которые они объединяют, и я хотел сохранить это в ребре.Я хотел объявить указатель типа Face и в конструкторе использовать класс:

Face * joiningFaces = new joiningFaces[2];

Когда я это делаю, я получаю синтаксические ошибки, которые говорят, что Face не является типом, даже если я включаю Face.h в Edge.h включает в себя.

Существует ли какая-то иерархическая система, которая мешает мне включать Edge в Face, а также Face в Edge?или я делаю что-то глупое?

=== Код ====

=== edge.h ===

#ifndef EDGE_H_
#define EDGE_H_
#include "Vertex.h"
#include "Face.h"



class Edge {

private:
    Vertex a;
    Vertex b;
    Face * joinsFace;

public:
    Edge();
    Edge(Vertex newa, Vertex newb);
...ect
};

=== Лицо.h ===

#ifndef FACE_H_
#define FACE_H_
#include "Edge.h"
class Face {


private:
    Edge a;
    Edge b;
    Edge c;

public:
    Face();
    Face(Edge newA, Edge newB, Edge newC);
    virtual ~Face();
    Edge getEdgeA();
    Edge getEdgeB();
    Edge getEdgeC();
};

#endif /* FACE_H_ */

Ответы [ 3 ]

5 голосов
/ 15 октября 2011

У вас есть круговая ссылка; если вам нужно только сослаться на указатели или ссылки на Face в Edge.h, то вы можете объявить вперед Face вместо включения Face.h:

class Face;

Подумайте, как работает включение: если бы вы вставили содержимое Face.h в Edge.h, а затем содержимое Edge.h в Face.h, вы бы получили бесконечный цикл; включают охранники, предотвращающие многократное включение:

#ifndef X_H
#define X_H

// ...

#endif

Но если у вас есть классы, которые ссылаются друг на друга, вы должны заранее объявить один или оба из них, чтобы разорвать цикл.

0 голосов
/ 15 октября 2011

Технически, вы должны создать прототип всех классов в заголовочном файле с расширением <name>.h, а затем записать код в соответствующий файл .cpp.Если класс должен ссылаться на другой класс, добавьте только включаемый файл в .h класса, который ссылается.Например, если грань относится к ребру, то добавьте edge.h к face.h.Не включайте edge.h в main.cpp (or wherever the main function is).Вы также можете написать код в самом файле '.h'.Выбор за вами.

0 голосов
/ 15 октября 2011

Если вы хотите объявить указатель на Face в классе ребер, компилятору необходимо объявить Face.Если вы создаете экземпляр объекта Face, компилятору необходимо определить класс Face.

// edge.hpp
class Face;  // forward declaration
class Edge
{
public:
  Edge(Face* myFace);
private:
  Face* myFace_;
};

// edge.cpp
#include face.hpp  // <- include the Face definition here

....
...