简体   繁体   English

C++ 类中的循环依赖

[英]Circular dependency in C++ classes

I am relatively new to C++, and facing a circular dependency problem.我对 C++ 比较陌生,并且面临循环依赖问题。 Can someone please help me solve this?有人可以帮我解决这个问题吗?

I have two classes:我有两节课:

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

All you need is to forward-declare the Edge class before it's used within the Vertex :您只需要在Edge类在Vertex中使用之前对其进行前向声明:

class Edge;

class Vertex {
    string name;
    int distance;
    ...
};

class Edge { ... };

You can't put members of type Vertex instead of the declaration of Vertex itself, since C++ doesn't allow recursive types.您不能放置Vertex类型的成员而不是Vertex本身的声明,因为 C++ 不允许递归类型。 Within the semantics of C++, the size of such type would need to be infinite.在 C++ 的语义中,这种类型的大小必须是无限的。

You can, of course, put pointers to Vertex within Vertex .当然,您可以在Vertex中放置指向Vertex的指针。

What you want, in fact, within Vertex 's edge and adjacency lists, is pointers, not copies of objects.实际上,在Vertex的边缘和邻接列表中,您想要的是指针,而不是对象的副本。 Thus, your code should be fixed like below (assuming you use C++11, which you in fact should be using now):因此,您的代码应该固定如下(假设您使用 C++11,实际上您现在应该使用它):

class Edge;

class Vertex {
    string name;
    int distance;
    int weight;
    bool known;
    list<shared_ptr<Edge>> edgeList;
    list<shared_ptr<Vertex>> adjVertexList;

public:
    Vertex();
    Vertex(const string & nm);
    virtual ~Vertex();
};

class Edge {
    Vertex target;
    int weight;

public:
    Edge();
    Edge(const Vertex & v, int w);
    virtual ~Edge();

    Vertex getTarget();
    void setTarget(const Vertex & target);
    int getWeight();
    void setWeight(int weight);
};

If you think about it, instantiating a single Vertex<\/code> or Edge<\/code> object would instantiate an infinite amount of more Vertex<\/code> and Edge<\/code> objects because each of them contain instances of each other.如果您考虑一下,实例化单个Vertex<\/code>或Edge<\/code>对象将实例化无限数量的Vertex<\/code>和Edge<\/code>对象,因为它们中的每一个都包含彼此的实例。

To fix this you need to forward declare a class, which one depends on the one you use first.要解决此问题,您需要转发声明一个类,该类取决于您首先使用的类。 Forward declaring classes allows you to use pointers and references to them without actually using<\/em> the class, only pointing to it.前向声明类允许您在不实际使用<\/em>类的情况下使用指针和对它们的引用,只指向它。

This snippet should be compilable but it will require some extra memory management.这个片段应该是可编译的,但它需要一些额外的内存管理。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM