考えてみると、単一のVertex
またはEdge
オブジェクトをインスタンス化すると、無限に多くのオブジェクトがインスタンス化Vertex
さEdge
れます。これは、それぞれが互いのインスタンスを含んでいるためです。
これを修正するには、最初に使用するクラスに依存するクラスを前方宣言する必要があります。クラスを前方宣言すると、クラスを実際に使用せずに、クラスを指すだけで、それらへのポインターと参照を使用できます。
このスニペットはコンパイル可能である必要がありますが、追加のメモリ管理が必要になります。
class Edge; // This is a forward declaration
class Vertex {
string name;
int distance;
//Vertex path;
int weight;
bool known;
list<Edge*> edgeList;
list<Vertex*> adjVertexList;
public:
Vertex();
Vertex(string nm);
virtual ~Vertex();
};
class Edge {
Vertex* target;
int weight;
public:
Edge();
Edge(Vertex* v, int w);
virtual ~Edge();
Vertex* getTarget();
void setTarget(Vertex* target);
int getWeight();
void setWeight(int weight);
};
クラスには、オブジェクト自体ではなく、オブジェクトへのポインターが含まれるようになったため、このコードはコンパイルされます。
BartoszKP が示唆しているように、前方宣言を読む必要があり、ポインターと参照についてももう少し学ぶ必要があるかもしれません。
あなたはまだ問題を抱えているので、私の答えをいくつかの詳細で更新します。クラスを実際に2つのヘッダーファイルに分割したと読みましたが、それらはVertex.h
とEdge.h
. 彼らはこのように見えるはずです
Vertex.h
class Edge;
class Vertex
{
Edge* CreateEdge(); // Declaration of a class function
// ...
};
Edge.h
class Vertex
class Edge
{
// ...
};
Edge
メンバーへのアクセスまたはインスタンスの作成にいつ使用するかの完全な定義を含める必要があります。基本的に、すべてのクラスと構造体が定義された後に、各関数の実装を配置する必要があります。これを行う最も簡単な方法は、関数の実装をそれぞれの.cpp
ファイルに入れることです。クラスEdge
内からオブジェクトを作成したいようですので、のファイルでそれを行う必要があります。Vertex
Vertex
.cpp
頂点.cpp
#include "Vertex.h"
#include "Edge.h"
Edge* Vertex::CreateEdge()
{
return new Edge();
}
この.cpp
ファイルで最初に行われるのは、それぞれのクラス定義を持つVertex
およびヘッダ ファイルをインクルードすることなので、必要に応じておよびクラスを完全に使用できます。Edge
Vertex
Edge
次のように宣言と定義を整理する方法には、特定の順序が必要です。
// Regarding global functions
Declaration // void MyFunction();
Definition // void MyFunction() { ... }
// Regarding classes and structs
Declaration // class MyClass; - Forward declaration in another header file
Definition // class MyClass { ... } - Definition in actual header file
// Regarding class functions
Declaration // class MyClass { void MyFunction(); }
Definition // void MyClass::MyFunction() { ... }