转发声明枚举类不起作用

Edd*_*223 12 c++ forward-declaration c++11 enum-class

在State.h我有

enum class StateID : unsigned int;
Run Code Online (Sandbox Code Playgroud)

在State.cpp我有

enum class StateID : unsigned int
{
    NullID = 0,
    MainMenuID,
    GamePlayID,
};
Run Code Online (Sandbox Code Playgroud)

问题是任何包含的类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的编译器标志.

Tim*_*mma 23

那是因为只有States.cpp知道里面存在的成员enum class ID.

包含States.hpp的文件只知道a 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 为令人回味的例子+1!"他再也看不出他卖的是什么样的水果......这就是为什么不包括fruit.hpp" - 天才. (3认同)