19

在 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,并且我在 nullptr、unique_ptr 等其他部分使用 c++11 功能,所以并不是我忘记了 c++11 的编译器标志。

4

1 回答 1

28

那是因为只有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;
}
于 2013-09-29T04:04:54.110 回答