那是因为只有States.cpp知道里面存在哪些成员enum class ID
。
包含States.hpp的文件只知道enum class ID
是 的大小,仅此而已unsigned int
。
您将需要使您的枚举值在标题中可用,以便任何需要了解枚举值的文件(例如MainMenuID
)都可以使用它们。
您可以制作一个单独的标头仅用于转发,可能称为StateFwd.hpp然后将您的State.cpp重命名为State.hpp。
您可以在何处/如何转发声明的示例
在我们在评论中进行的讨论之后,我用一个例子更新了我的答案。
水果.hpp
任何选择包含此标题的人都会知道存在什么样的水果。
#ifndef FRUIT_HPP
#define FRUIT_HPP
enum class Fruit
{
APPLE,
ORANGE,
BANANA
};
#endif
村庄.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
农民.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;
}
}
商人.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;
}
}
例子.cpp
这把它拉到了一起。在我们的示例中,我们希望农民去买一些水果。我们确切地知道我们想要什么样的水果;一根香蕉。因此我们需要包含fruit.hpp,否则我们无法告诉农民去为我们买香蕉。
在这种情况下,唯一知道存在哪种水果的人是我们(example.cpp)和农民(farmer.cpp)。农民甚至不需要知道。就好像我们给了他一张折叠的纸,上面写着我们想要什么水果,但我们告诉他不要看它。他只是把它交给不会阅读的商人,所以他只是把它传递给农民。
#include "village.hpp"
#include "fruit.hpp"
int main()
{
peasant::buy_fruit(Fruit::BANANA, 25.0f);
return 0;
}