如何在不同文件中使用extern

问题描述 投票:0回答:1

我有这些文件结构。

main.cpp

#include "main.h"
Map map;
Fruit fruit;
Stone stone;

main.h

extern Map map;
extern Fruit fruit;
extern Stone stone;

地图.h

#include "main.h"
class Map {public: int size = 20;};

水果.h

#include "main.h"
class Fruit { public: int pos = 1; draw() {return map.size;} };

stone.h

#include "main.h"
class Stone { public: draw() {return map.size * fruit.pos;} };

问题是当我尝试使用 map.sizefruit.pos 我得到了错误。

'map': undeclared identifier

同样的错误: stone. 那么,有什么问题呢?

c++ extern
1个回答
2
投票

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;

这不是你应该写代码的方式。


0
投票

文件 (*.h*.cpp)只应包括它们直接依赖的文件。

文件不应该包含它们不依赖的文件。

打破周期性依赖的一种方法是将实现置于 foo.cpp 源文件中,而不是在 foo.h 头文件。

打破对全局变量依赖性的一种方法是将它们作为参数传递进来,而不是将它们硬编码到例程中。

使用前向声明可以避免包含一个仅用于声明类型的头文件。 只有当类型的细节,如它的方法和足迹并不重要时,才可以使用。 唉,模板类的正向声明就比较棘手了。

对于OP例子中的文件,这里有一个融合了这些建议的替代实现。

fruit.h

#ifndef FRUIT_H
#define FRUIT_H

class Map;

class Fruit {
public:
    int pos = 1;
    auto draw(Map const&) -> int;
};

#endif

map.h

#ifndef MAP_H
#define MAP_H

class Map {
public:
    int size = 20;
};

#endif

石头.h

#ifndef STONE_H
#define STONE_H

class Fruit;
class Map;

class Stone {
public:
    auto draw(Map const& map, Fruit const& fruit) -> int;
};

#endif

map.h stone.h

// Identity.
#include "fruit.h"

// Other dependencies.
#include "map.h"

auto Fruit::draw(Map const& map) -> int {
    return map.size;
}

石头.cpp

// 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;
}

main.cpp

#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";
}
© www.soinside.com 2019 - 2024. All rights reserved.