Avraam Mavridis
Avraam Mavridis

Reputation: 8920

Class forward declaration leads to incomplete type

I have the following code:

class Node;

class Edge {
    public:
    //Edge(Node originnode,Node targetnode,int weight):OriginNode(originnode),TargetNode(targetnode),Weight(weight){};
    //~Edge(){};
    //Node getOriginNode() const { return OriginNode;};
    //Node getTargetNode() const { return TargetNode;};
    int getWeight() const { return Weight;};
    Node OriginNode;
    Node TargetNode;
    int Weight;
};

class Node{
    public:
    std::string getName();
    std::vector<Edge> getEdges();
};

when I am trying to compile the compiler claims that OriginNode and TargetNode have incomplete type. I have already forward declare the Node. How can I fix that?

Upvotes: 0

Views: 122

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311126

You should reverse the order of declarations

class Edge;

class Node{
    public:
    std::string getName();
    std::vector<Edge> getEdges();
};

class Edge {
    public:
    //Edge(Node originnode,Node targetnode,int weight):OriginNode(originnode),TargetNode(targetnode),Weight(weight){};
    //~Edge(){};
    //Node getOriginNode() const { return OriginNode;};
    //Node getTargetNode() const { return TargetNode;};
    int getWeight() const { return Weight;};
    Node OriginNode;
    Node TargetNode;
    int Weight;
};

Nevertheless I consider that design of classes as very bad. Node is a primitive entity that should not contain a vector of Edge. Why should Node control the container?! The container is a more high -level generalization than Node. So it should be placed in a more high level compared with Node.

Upvotes: 0

pan-
pan-

Reputation: 153

With boost::container you can change the order of the declarations because it support containers of incomplete types :

    class Edge;

class Node{
    public:
    std::string getName();
    boost::container::vector<Edge> getEdges();
};

class Edge {
    public:
    //Edge(Node originnode,Node targetnode,int weight):OriginNode(originnode),TargetNode(targetnode),Weight(weight){};
    //~Edge(){};
    //Node getOriginNode() const { return OriginNode;};
    //Node getTargetNode() const { return TargetNode;};
    int getWeight() const { return Weight;};
    Node OriginNode;
    Node TargetNode;
    int Weight;
};

By the way, why do you want to return a value of the Edge vector when you get them from the Node and why do you store the value of the OriginNode and TargetNode inside the edge, you can use references or pointers instead (maybe I'm wrong, I don't know all your requirements).

Upvotes: 0

Luchian Grigore
Luchian Grigore

Reputation: 258648

You can't without providing a full definition of Node. You can alternatively declare pointers as members: Node* OriginNode.

I'd suggest you re-think your design though - does an Edge really have a Node. As in - does it have ownership over it? Can't a Node be shared between multiple edges? Also, Does a Node really contain multiple edges?

Upvotes: 5

Related Questions