那是因为只有
States.cpp 知道在
enum class ID
中存在哪些成员。
包含 States.hpp 的文件只知道 enum class ID
是一个无符号整数的大小,仅此而已。
您需要在头文件中公开枚举值,以便任何需要知道枚举值(例如MainMenuID
)的文件都可以使用它们。
您可以创建一个专门用于转发的头文件,例如StateFwd.hpp,然后将您的State.cpp重命名为State.hpp。
您可能如何进行前向声明的示例
我已经在评论中的讨论后更新了我的答案。
fruit.hpp
任何选择包含此头文件的人都会知道哪些水果存在。
#ifndef FRUIT_HPP
#define FRUIT_HPP
enum class Fruit
{
APPLE,
ORANGE,
BANANA
};
#endif
village.hpp
这个村庄里充满了因为对水果的渴望而驱使着他们的人。
#ifndef VILLAGE_HPP
#define VILLAGE_HPP
enum class Fruit;
namespace farmer
{
bool is_fruit_for_sale(Fruit fruit);
float get_cost_of_fruit(Fruit fruit);
}
namespace blind_but_greedy_merchant
{
bool sell_fruit(Fruit fruit, float money);
}
namespace peasant
{
inline bool buy_fruit(Fruit fruit, float money)
{
return blind_but_greedy_merchant::sell_fruit(fruit, money);
}
}
#endif
farmer.cpp
这位农民只种植苹果和橙子,所以他从不出售香蕉。
#include "fruit.hpp"
namespace farmer
{
bool is_fruit_for_sale(Fruit fruit)
{
switch ( fruit ) {
case Fruit::APPLE:
case Fruit::ORANGE:
return true;
case Fruit::BANANA:
return false;
}
return false;
}
float get_cost_of_fruit(Fruit fruit)
{
switch ( fruit ) {
case Fruit::APPLE:
return 1.00f;
case Fruit::ORANGE:
return 2.50f;
case Fruit::BANANA:
return 200.0f;
}
return 0.0f;
}
}
merchant.cpp
这个商人因为贪婪而变得盲目。他已经看不清自己在卖什么水果了。尽管如此,他仍然知道如何与农民打交道,将客户的请求转达给农民,并为所有水果添加高额利润。
这就是为什么fruit.hpp没有被包含进来的原因。
#include "village.hpp"
namespace blind_but_greedy_merchant
{
bool sell_fruit(Fruit fruit, float money)
{
if ( !farmer::is_fruit_for_sale(fruit) ) {
return false;
}
float inflatedcost = farmer::get_cost_of_fruit(fruit) * 3;
if ( money < inflatedcost ) {
return false;
}
return true;
}
}
example.cpp
这将所有东西都串联在一起。在我们的例子中,我们想让农民去买一些水果。
我们知道我们想要什么样的水果; 香蕉。因此,我们需要包含fruit.hpp,否则我们就不能告诉农民为我们买香蕉。
在这种情况下,唯一知道存在什么样的水果的人只有我们(example.cpp)和农民(farmer.cpp)。
农民不需要知道水果的种类。这就像是我们给了他一张折叠好的纸条,上面写着我们想要的水果,但我们告诉他不要看。然后他只是把它递给了商贩,商贩看不懂纸条,于是就把它递给了农民。
#include "village.hpp"
#include "fruit.hpp"
int main()
{
peasant::buy_fruit(Fruit::BANANA, 25.0f);
return 0;
}