【问题标题】:Classes in different headers do not recognize each other?不同标题中的类不能相互识别?
【发布时间】:2018-09-27 07:41:14
【问题描述】:

尽管 Visual Studio 预编译器或其他任何名称将 Graph 识别为来自不同标头的类,但在构建之后,我得到了最荒谬的错误,就好像我以前从未提及其他标头一样。首先,我没有前向声明两个类,下面的第一组错误来自于此,但后来我尝试前向声明,并且与类本身的结构相关的类似错误。使用来自另一个类的函数会产生它们,这表明头文件什么都不做。他们不知道彼此的功能,我也不知道为什么。

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

行严重性描述文件 11 错误语法错误:缺少 ';' 前 '*' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 34 错误“_master”:未声明 标识符 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 11 错误缺少类型说明符 - 假定为 int。注意:C++ 没有 支持 默认整数 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 11 错误之前的意外令牌 ';' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 30 错误语法错误:标识符 '图' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 34 错误“主”:未声明 标识符 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\vertex.h 线路严重性描述文件 8 错误“顶点”:未声明 标识符 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h

前向声明后出现的错误:

行严重性描述文件 28 错误使用未定义类型 '顶点' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 28 '->getChainComponent_id' 左边的错误必须指向 类/结构/联合/通用 键入 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 错误使用未定义类型 '顶点' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 '->DFS' 左侧的错误必须指向类/结构/联合/通用 键入 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 57 错误使用未定义类型 '顶点' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h

【问题讨论】:

  • 你需要像class Graph;这样的前向声明。
  • 不,我尝试向前声明它,但我得到了其他错误,即有另一个类,但不知道它的结构,当我使用它的函数时,我得到了这些错误。跨度>
  • @ХристоИванов 只需将两个类放在同一个标​​题中即可。是否前向声明问题的根本原因是您的标头中有循环依赖。您要么必须打破这种依赖关系,要么将两个标题合并为一个。
  • 显示真实的代码将有助于获得有关如何打破依赖关系的最佳建议。
  • @ХристоИванов 是的,为了访问这些类的成员,定义必须可用,但是为了在您的问题中声明这些类,前向声明就足够了。带有类定义的标题可以在以后包含。

标签: c++ visual-studio-2017 header-files circular-dependency


【解决方案1】:

这是一个循环依赖问题;这两个头文件相互包含。

对于这两种情况,只有forward declaration 就足够了;声明一个指向类的指针不需要类是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;
};

编辑

将成员函数的实现移至实现文件。例如

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

正如@M.M 所指出的,对于Vertex.h 中的Graph 类,前向声明就足够了。所以你可以在Vertex.h中删除#include "Graph.h",并在Graph.h中保留#include "Vertex.h"

【讨论】:

  • 我已经试过了。这是我从函数中得到的: 28 错误使用未定义类型 'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 28 '->getChainComponent_id' 左侧的错误必须指向类/struct/union/generic type c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h 30 错误使用未定义类型'Vertex' c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph .h 30 '->DFS' 左侧的错误必须指向类/结构/联合/通用类型 c:\users\bico\source\repos\longestchaingraph\longestchaingraph\graph.h
  • @ХристоИванов 在您发布的代码中没有提到getChainComponent_id,您需要发布真实代码。
  • 这里是完整的代码。我曾尝试向前声明它,但它只显示了头类,而不是它们的结构。我认为这毫无意义,所以我恢复了前向声明,但这里是代码和所有错误,无论有无前向声明。
  • 转发 dec 不足以满足 OP。如果是这样的话,那将是stackoverflow.com/q/625799/5470596 的完美翻版。他们需要将所有实现放在单独的文件中。
  • @YSC 对于问题中发布的代码,Graph 的前向声明就足够了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
相关资源
最近更新 更多