C++:相互包含头文件
C++: Including header files in each other
所以我看到有人问过这个问题,但是人们提供的例子非常简单(他们 类 没有构造函数或方法)而且我不知道如何将解决方案扩展到更复杂的情况.
我尝试过使用前向声明和指针,只是前向声明,只是指针,甚至是前向声明和类型名定义,所有这些都是其他更简单的帖子建议的解决方案,none 已经奏效(未知标识符或不完整的类型错误)。那么我怎样才能让下面的两个文件正确编译并按我的预期使用呢?
Unit.hpp:
#ifndef PROJECT_UNIT_HPP
#define PROJECT_UNIT_HPP
#include "GridNode.hpp"
class Unit
{
private:
/* Fields */
int xPos, yPos, ownerID;
std::vector<GridNode> influenceMap;
public:
/* Constructors */
Unit(int x, int y, int id) : xPos(x), yPos(y), ownerID(id)
{
influenceMap.push_back( GridNode() );
}
/* Methods */
std::vector<GridNode> getMap() {return influenceMap;}
};
#endif
GridNode.hpp:
#ifndef PROJECT_GRIDNODE_HPP
#define PROJECT_GRIDNODE_HPP
#include "Unit.hpp"
class GridNode
{
private:
/* Members */
int id;
std::vector<Unit> nodeUnits;
public:
/* Static vars */
static int nodeLength;
/* Constructors */
GridNode()
{
std::cout << "Reached here!\n";
}
};
#endif
您需要前向声明并将成员函数主体(包括构造函数和析构函数)移出 class 主体,并在包含其他 class 定义之后。
即使隐式构造函数和析构函数也会破坏事物,您将需要显式的用户提供的声明(尽管您可以通过 = default
使用编译器提供的定义)
class GridNode;
class Unit
{
private:
/* Fields */
int xPos, yPos, ownerID;
std::vector<GridNode> influenceMap;
public:
/* Constructors */
Unit(int x, int y, int id);
Unit(const Unit&);
~Unit();
/* Methods */
std::vector<GridNode> getMap();
};
#include "GridNode.hpp"
inline Unit::Unit(int x, int y, int id) : xPos(x), yPos(y), ownerID(id)
{
influenceMap.push_back( GridNode() );
}
inline Unit::Unit(const Unit&) = default;
inline Unit::~Unit() = default;
inline std::vector<GridNode> Unit::getMap() {return influenceMap;}
您需要做的就是在两者中 #include <vector>
并在 GridNode.hpp
中转发声明 class Unit;
:
#ifndef PROJECT_GRIDNODE_HPP
#define PROJECT_GRIDNODE_HPP
// using std::vector
#include <vector>
// Forward declare
class Unit;
class GridNode
{
private:
/* Members */
int id;
std::vector<Unit> nodeUnits;
public:
/* Static vars */
static int nodeLength;
/* Constructors */
GridNode()
{
std::cout << "Reached here!\n";
}
};
#endif
所以我看到有人问过这个问题,但是人们提供的例子非常简单(他们 类 没有构造函数或方法)而且我不知道如何将解决方案扩展到更复杂的情况.
我尝试过使用前向声明和指针,只是前向声明,只是指针,甚至是前向声明和类型名定义,所有这些都是其他更简单的帖子建议的解决方案,none 已经奏效(未知标识符或不完整的类型错误)。那么我怎样才能让下面的两个文件正确编译并按我的预期使用呢?
Unit.hpp:
#ifndef PROJECT_UNIT_HPP
#define PROJECT_UNIT_HPP
#include "GridNode.hpp"
class Unit
{
private:
/* Fields */
int xPos, yPos, ownerID;
std::vector<GridNode> influenceMap;
public:
/* Constructors */
Unit(int x, int y, int id) : xPos(x), yPos(y), ownerID(id)
{
influenceMap.push_back( GridNode() );
}
/* Methods */
std::vector<GridNode> getMap() {return influenceMap;}
};
#endif
GridNode.hpp:
#ifndef PROJECT_GRIDNODE_HPP
#define PROJECT_GRIDNODE_HPP
#include "Unit.hpp"
class GridNode
{
private:
/* Members */
int id;
std::vector<Unit> nodeUnits;
public:
/* Static vars */
static int nodeLength;
/* Constructors */
GridNode()
{
std::cout << "Reached here!\n";
}
};
#endif
您需要前向声明并将成员函数主体(包括构造函数和析构函数)移出 class 主体,并在包含其他 class 定义之后。
即使隐式构造函数和析构函数也会破坏事物,您将需要显式的用户提供的声明(尽管您可以通过 = default
使用编译器提供的定义)
class GridNode;
class Unit
{
private:
/* Fields */
int xPos, yPos, ownerID;
std::vector<GridNode> influenceMap;
public:
/* Constructors */
Unit(int x, int y, int id);
Unit(const Unit&);
~Unit();
/* Methods */
std::vector<GridNode> getMap();
};
#include "GridNode.hpp"
inline Unit::Unit(int x, int y, int id) : xPos(x), yPos(y), ownerID(id)
{
influenceMap.push_back( GridNode() );
}
inline Unit::Unit(const Unit&) = default;
inline Unit::~Unit() = default;
inline std::vector<GridNode> Unit::getMap() {return influenceMap;}
您需要做的就是在两者中 #include <vector>
并在 GridNode.hpp
中转发声明 class Unit;
:
#ifndef PROJECT_GRIDNODE_HPP
#define PROJECT_GRIDNODE_HPP
// using std::vector
#include <vector>
// Forward declare
class Unit;
class GridNode
{
private:
/* Members */
int id;
std::vector<Unit> nodeUnits;
public:
/* Static vars */
static int nodeLength;
/* Constructors */
GridNode()
{
std::cout << "Reached here!\n";
}
};
#endif