我有这些文件结构。
#include "main.h"
Map map;
Fruit fruit;
Stone stone;
extern Map map;
extern Fruit fruit;
extern Stone stone;
#include "main.h"
class Map {public: int size = 20;};
#include "main.h"
class Fruit { public: int pos = 1; draw() {return map.size;} };
#include "main.h"
class Stone { public: draw() {return map.size * fruit.pos;} };
问题是当我尝试使用 map.size
和 fruit.pos
我得到了错误。
'map': undeclared identifier
同样的错误: stone
. 那么,有什么问题呢?
main.h
应该包括 map.h
而不是相反。
main.h
应包括 fruit.h
而不是相反。
main.h
应包括 stone.h
而不是相反。
另外,你应该加上 包庇 到你的头文件。
编辑
这里有一个工作方法,(我不能相信我推荐这样的代码,但还是)
// map.h
#ifndef MAP_H
#define MAP_H
class Map {public: int size = 20};
extern Map map;
#endif
// fruit.h
#ifndef FRUIT_H
#define FRUIT_H
#include "map.h"
class Fruit { public: int pos = 1; draw() {return map.size;} };
extern Fruit fruit;
#endif
// stone.h
#ifndef STONE_H
#define STONE_H
#include "map.h"
#include "fruit.h"
class Stone { public: draw() {return map.size * fruit.pos;} };
extern Stone stone;
#endif
// main.cpp
#include "map.h"
#include "fruit.h"
#include "stone.h"
Map map;
Fruit fruit;
Stone stone;
这不是你应该写代码的方式。
文件 (*.h
或 *.cpp
)只应包括它们直接依赖的文件。
文件不应该包含它们不依赖的文件。
打破周期性依赖的一种方法是将实现置于 foo.cpp
源文件中,而不是在 foo.h
头文件。
打破对全局变量依赖性的一种方法是将它们作为参数传递进来,而不是将它们硬编码到例程中。
使用前向声明可以避免包含一个仅用于声明类型的头文件。 只有当类型的细节,如它的方法和足迹并不重要时,才可以使用。 唉,模板类的正向声明就比较棘手了。
对于OP例子中的文件,这里有一个融合了这些建议的替代实现。
#ifndef FRUIT_H
#define FRUIT_H
class Map;
class Fruit {
public:
int pos = 1;
auto draw(Map const&) -> int;
};
#endif
#ifndef MAP_H
#define MAP_H
class Map {
public:
int size = 20;
};
#endif
#ifndef STONE_H
#define STONE_H
class Fruit;
class Map;
class Stone {
public:
auto draw(Map const& map, Fruit const& fruit) -> int;
};
#endif
// Identity.
#include "fruit.h"
// Other dependencies.
#include "map.h"
auto Fruit::draw(Map const& map) -> int {
return map.size;
}
// Identity.
#include "stone.h"
// Other dependencies.
#include "fruit.h"
#include "map.h"
auto Stone::draw(Map const& map, Fruit const& fruit) -> int {
return map.size * fruit.pos;
}
#include <iostream>
#include "fruit.h"
#include "map.h"
#include "stone.h"
using std::cout;
int main() {
auto map = Map{};
auto fruit = Fruit{};
auto stone = Stone{};
map.size = 17;
fruit.pos = 3;
cout << "map.size is " << map.size << "\n";
cout << "fruit.pos is " << fruit.pos << "\n";
cout << "fruit.draw(map) is " << fruit.draw(map) << "\n";
cout << "stone.draw(map, fruit) is " << stone.draw(map, fruit) << "\n";
}