Переадресация объявления класса enum не работает
В State.h у меня есть
enum class StateID : unsigned int;
В State.cpp у меня есть
enum class StateID : unsigned int
{
NullID = 0,
MainMenuID,
GamePlayID,
};
Проблема в том, что любой класс, который включает в себя State.h
имеет предварительное объявление, но я не могу использовать любой enum
значение в любом файле cpp, кроме States.cpp
(который определил это), как StateID::MainMenuID
, Ошибка говорит...
/home/lee/Projects/SuddenAwakening/Source/Game.cpp:24: ошибка: "MainMenuID" не является членом "StateID"
Я использую LinuxMint15KDE, g++ 4.7, и я использую функции C++11 в других частях, таких как nullptr, unique_ptr, ect..., поэтому я не забыл флаг компилятора для C++11.
1 ответ
Это потому, что только States.cpp знает, какие члены существуют внутри enum class ID
,
Файлы, которые содержат States.hpp, знают только, что enum class ID
это размер unsigned int
и это все.
Вам нужно будет сделать ваши значения перечисления доступными в заголовке, чтобы любой файл, который должен знать о перечисляемых значениях (например, 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;
}