我有2个类用2个不同的文件编写:router.h - router.cpp和topology.h - topology.cpp。
我将显示.h文件的内容,因为.cpp文件只包含实现。
router.h:
#ifndef _ROUTER_H_
#define _ROUTER_H_
#include <map>
#include "topology.h"
using namespace std;
class Router {
public:
int id;
map<Router, int> linkers;
Topology topology;
Router();
Router(int id);
void addLink(Router router, int cost);
void delLink(Router router);
};
#endif
topology.h:
#ifndef _TOPOLOGY_H_
#define _TOPOLOGY_H_
#include "router.h"
class Topology {
public:
map<Router, int> graph;
Topology();
void addNode(Router router, int cost);
void delNode(Router router);
};
#endif
我的问题是,为什么在编译时我有一个由无法识别的路由器和拓扑类引起的错误,即使我包含了标题,我添加了ifndefs以便不包含多个文件?我在网上查了一下,也没有找到关于这个问题的任何内容。
答案 0 :(得分:1)
此代码中的问题是拓扑(Topology.h)使用通过值传递的Router对象:编译器需要具有Router的完整定义。没问题,所以你包括Router.h。 但是,您的路由器需要一个完整的拓扑对象(不是指针,而不是引用)才能工作。
所以你有一个配置,其中A需要B完全声明完全声明,B需要A完全声明完全声明自己。如评论中所述,这是循环依赖关系中的一个问题。
你应该做的是避免路由器中的拓扑对象(你可能需要一个指针,因为一个完整的对象意味着复制而不是共享实例)。在Router.h中使用拓扑的前向声明(以及Router.cpp中的#include "Topology"
)并声明您的&#34;拓扑&#34;属性为指针/智能指针/引用。
答案 1 :(得分:1)
router.h
包括topology.h
,其中包含router.h
,因为包含警卫,然后在其定义中使用未定义的类Router
。标准解决方案是转发声明类型(例如class Router;
)。遗憾的是std::map
需要完整类型,并且使用不完整类型的行为是未定义的行为。要使地图与不完整类型兼容,您可以使用std::unique_ptr<map<Router, int>>
(或其他指针类型)或boost::container::map<Router, int>>
。