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
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<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);
};
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() { ... }
All you need is to forward-declare the Edge
class before it's used within the 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. Within the semantics of C++, the size of such type would need to be infinite.
You can, of course, put pointers to Vertex
within Vertex
.
What you want, in fact, within Vertex
's edge and adjacency lists, is pointers, not copies of objects. Thus, your code should be fixed like below (assuming you use C++11, which you in fact should be using now):
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);
};