3

私は C++ に比較的慣れておらず、循環依存の問題に直面しています。誰かがこれを解決するのを手伝ってくれますか?

私は2つのクラスを持っています:

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);
};

上記のコードでは、次のエラーが発生します。

  • 「頂点」はタイプを指定していません
  • 「頂点」が宣言されていません
  • 'v' の前に ')' が必要</li>

この問題を解決するにはどうすればよいですか?

4

2 に答える 2

2

考えてみると、単一のVertexまたはEdgeオブジェクトをインスタンス化すると、無限に多くのオブジェクトがインスタンス化VertexEdgeれます。これは、それぞれが互いのインスタンスを含んでいるためです。

これを修正するには、最初に使用するクラスに依存するクラスを前方宣言する必要があります。クラスを前方宣言すると、クラスを実際に使用せずに、クラスを指すだけで、それらへのポインターと参照を使用できます。

このスニペットはコンパイル可能である必要がありますが、追加のメモリ管理が必要になります。

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.hEdge.h. 彼らはこのように見えるはずです

Vertex.h

class Edge;
class Vertex
{
    Edge* CreateEdge(); // Declaration of a class function
    // ...
};

Edge.h

class Vertex
class Edge
{
    // ...
};

Edgeメンバーへのアクセスまたはインスタンスの作成にいつ使用するかの完全な定義を含める必要があります。基本的に、すべてのクラスと構造体が定義された後に、各関数の実装を配置する必要があります。これを行う最も簡単な方法は、関数の実装をそれぞれの.cppファイルに入れることです。クラスEdge内からオブジェクトを作成したいようですので、のファイルでそれを行う必要があります。VertexVertex.cpp

頂点.cpp

#include "Vertex.h"
#include "Edge.h"

Edge* Vertex::CreateEdge()
{
    return new Edge();
}

この.cppファイルで最初に行われるのは、それぞれのクラス定義を持つVertexおよびヘッダ ファイルをインクルードすることなので、必要に応じておよびクラスを完全に使用できます。EdgeVertexEdge

次のように宣言と定義を整理する方法には、特定の順序が必要です。

// 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() { ... }
于 2013-09-22T00:14:01.070 に答える