0

Even though the visual studio pre-compiler or whatever it's called recognizes Graph as a class from a different header, after building I get the most ridiculous errors acting as if I've never mentioned the other headers before. First I didn't forward declare both classes and the first set of errors below come from this, but then I tried forward declaring and there are similar errors related to the structure of the classes themselves. Using functions from another class produce them which shows me the header files do NOTHING. They don't know about each other's functions and I don't know why.

Vertex.h :

#pragma once
#include "Graph.h"
#include <vector>

class Graph;
class Vertex
{
    int unique_id;
    int longestChain = 0;
    int chainComponent_id;
    std::vector<int> edges;
    Graph* master;
public:
    int get_id()
    {
        return unique_id;
    }

    int getChainComponent_id()
    {
        return chainComponent_id;
    }

    void setChainComponent_id(int id)
    {
        chainComponent_id = id;
    }

    int DFS(int, int);

    Vertex(int id, std::vector<int> _edges, Graph* _master)
    {
        unique_id = id;
        edges = _edges;
        master = _master;
        longestChain = 0;
        chainComponent_id = -1;
    }
};

Graph.h :

#pragma once
#include "Vertex.h"
#include <vector>
#include <iostream>
class Vertex;
class Graph
{
    std::vector<Vertex*> vertex;
    int amountOfChainComponents = 0;
public:
    Vertex* getVertex(int id)
    {
        if(id<0 || id>vertex.size())
        {
            return nullptr; //shouldn't be possible with proper input
        }
        return vertex[id];
    }
    int getAmountOfChainComponents()
    {
        return amountOfChainComponents;
    }
    int longestChain()
    {
        int longest = 0;
        for(int i = 0; i < vertex.size(); i++)
        {
            if(vertex[i]->getChainComponent_id() == -1)
            {
                int tmp = vertex[i]->DFS(0, amountOfChainComponents);
                amountOfChainComponents++;
                if(tmp > longest)
                {
                    longest = tmp;
                }
            }
        }
        if(longest == -1)
        {
            std::cout << "There is a chain for every positive integer" << std::endl;
            return -1;
        }
        if(longest < 2)
        {
            std::cout << "There is no chain" << std::endl;
            return 0;
        }

        return longest;

    }
    Graph(std::vector<std::vector<int>> vertices)
    {
        amountOfChainComponents = 0;
        for(int i = 0; i < vertices.size(); i++)
        {
            Vertex* tmp = new Vertex(i, vertices[i], this);
            vertex.push_back(tmp);
        }
    }
    ~Graph()
    {
        while(!vertex.empty())
        {
            delete vertex[vertex.size() - 1];
            vertex.pop_back();
        }
    }
};

Line Severity Description File 11 Error syntax error: missing ';' before '*' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 34 Error '_master': undeclared identifier c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 11 Error missing type specifier - int assumed. Note: C++ does not support default-int c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 11 Error unexpected token(s) preceding ';' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 30 Error syntax error: identifier 'Graph' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 34 Error 'master': undeclared identifier c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h Line Severity Description File 8 Error 'Vertex': undeclared identifier c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h

Errors that come after forward declaration:

Line Severity Description File 28 Error use of undefined type 'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 28 Error left of '->getChainComponent_id' must point to class/struct/union/generic type c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 Error use of undefined type 'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 Error left of '->DFS' must point to class/struct/union/generic type c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 57 Error use of undefined type 'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • 3
    You need forward declarations like `class Graph;`. – user7860670 Sep 27 '18 at 07:42
  • Nope, I tried forward declaring it, but I get other errors, that get that there is another class, but don't know it's structure and when I use it's functions I get these errors. – Христо Иванов Sep 27 '18 at 07:47
  • @ХристоИванов Just put the two classes in the same header then. Forward declarations or not the root cause of your problems is that you have a circular dependency in your headers. You either have to break that dependency, or merge the two headers into one. – john Sep 27 '18 at 07:49
  • Showing the real code would help with best advice on how to break the dependencies. – john Sep 27 '18 at 07:50
  • @ХристоИванов Yes, in order to access members of these classes definition must be available, however in order to declare these classes as written in your question forward declaration will be sufficient. Header with class definition can be included later. – user7860670 Sep 27 '18 at 07:55
  • Here is the entire code. I had tried forward declaring it but it only showed the header classes, not their structure. I thought it was pointless so I reverted the forward declarations, but here is the code and all it's errors with and without forward declaring. – Христо Иванов Sep 27 '18 at 08:03

1 Answers1

6

This is a circular dependency issue; the two header files are including each other.

For both cases, only forward declaration will be enough; declare a pointer to class doesn't need the class to be complete type.

Vertex.h

#pragma once
#include <vector>

class Graph;
class Vertex
{
    int unique_id;
    int longestChain = 0;
    int chainComponent_id;
    std::vector<int> edges;
    Graph* master;
};

Graph.h

#pragma once
#include <vector>
#include <iostream>

class Vertex;
class Graph
{
    std::vector<Vertex*> vertex;
    int amountOfChainComponents = 0;
};

EDIT

Move member functions' implementations to implementation files. e.g.

Vertex.h

#pragma once
#include <vector>

class Graph;
class Vertex
{
    int unique_id;
    int longestChain = 0;
    int chainComponent_id;
    std::vector<int> edges;
    Graph* master;
public:
    int get_id();
    ...
};

Vertex.cpp

#pragma once
#include "Vertex.h"
#include "Graph.h"

int Vertex::get_id()
{
    return unique_id;
}
...

Graph.h

#pragma once
#include <vector>
#include <iostream>

class Vertex;
class Graph
{
    std::vector<Vertex*> vertex;
    int amountOfChainComponents = 0;
public:
    Vertex* getVertex(int id);
    ...
};

Graph.cpp

#pragma once
#include "Vertex.h"
#include "Graph.h"

Vertex* Graph::getVertex(int id)
{
    if(id<0 || id>vertex.size())
    {
        return nullptr; //shouldn't be possible with proper input
    }
    return vertex[id];
}
...

EDIT2

As @M.M pointed, forward declaration is enough for class Graph in Vertex.h. So you can just remove #include "Graph.h" in Vertex.h, and reserve #include "Vertex.h" in Graph.h.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • I already tried this. This is what I get from within the functions: 28 Error use of undefined type 'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 28 Error left of '->getChainComponent_id' must point to class/struct/union/generic type c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 Error use of undefined type 'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 Error left of '->DFS' must point to class/struct/union/generic type c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h – Христо Иванов Sep 27 '18 at 07:49
  • 2
    @ХристоИванов In your posted code there is no mention of `getChainComponent_id`, you need to post the real code. – john Sep 27 '18 at 07:52
  • Here is the entire code. I had tried forward declaring it but it only showed the header classes, not their structure. I thought it was pointless so I reverted the forward declarations, but here is the code and all it's errors with and without forward declaring. – Христо Иванов Sep 27 '18 at 08:03
  • @ХристоИванов You have to remove `#include "Graph.h"` from `vertex.h` – M.M Sep 27 '18 at 08:05
  • 2
    Forward dec won't b enought for OP. If it were the case it would be a perfect dup of https://stackoverflow.com/q/625799/5470596. They need to put all implementaiton in separate files. – YSC Sep 27 '18 at 08:06
  • 1
    @YSC for the code posted in the question, forward declaration of Graph is sufficient – M.M Sep 27 '18 at 08:08
  • @M.M I won't bet on the fact that OP showed us their code as it is actually ;) – YSC Sep 27 '18 at 08:10
  • I did. https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes answers my questions why I need to forward declare only 1 of the classes. And I was going to make cpp files after I fixed the error with the headers. Didn't realise it helped fixing them. – Христо Иванов Sep 27 '18 at 08:20