转发声明枚举类不起作用

时间:2013-09-29 03:24:45

标签: c++ c++11 forward-declaration enum-class

在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的编译器标志。 / p>

1 个答案:

答案 0 :(得分:20)

那是因为只有 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;
}