Переадресация объявления класса 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;
}
Другие вопросы по тегам