Circular dependency in C++ classes

后端 未结 2 2004
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-11 08:42

I am relatively new to C++, and facing a circular dependency problem. Can someone please help me solve this?

I have two classes:

class Vertex {
    s         


        
2条回答
  •  一向
    一向 (楼主)
    2020-12-11 09:28

    If you think about it, instantiating a single Vertex or Edge object would instantiate an infinite amount of more Vertex and Edge objects because each of them contain instances of each other.

    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 the class, only pointing to it.

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

    This piece of code compiles because the classes now contain pointers to objects instead of the objects themselves.

    As BartoszKP suggests you should read up on forward declarations and you might need to learn a bit more about pointers and references as well.


    Since you are still having trouble I will update my answer with some more details. I read that you have actually split your classes into two header files now, I assume they are Vertex.h and Edge.h. They should look something like this

    Vertex.h

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

    Edge.h

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

    You will need to include the complete definition of Edge when you want to use it for accessing its members or creating an instance. Basically you need to put the implementations of each function after all classes and structs have been defined. The easiest way to do this is by putting the function implementations in their respective .cpp file. It seems you want to create an Edge object from within the Vertex class, so you need to do that in your Vertex's .cpp file.

    Vertex.cpp

    #include "Vertex.h"
    #include "Edge.h"
    
    Edge* Vertex::CreateEdge()
    {
        return new Edge();
    }
    

    Because the first thing done in this .cpp file is including the Vertex and Edge header files, that have their respective class definitions, you can completely use the Vertex and Edge classes as you want.

    You will need a certain order in how you organize your declarations and definitions which goes like this

    // 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() { ... }
    

提交回复
热议问题