0

C++: Как использовать одни и те же имена членов перечисления в разных перечислениях без ошибки переопределения?

16

У меня есть файл конфигурации, который я включаю во все свои файлы. В нем содержатся различные перечисления (enums), но в каждом перечислении имеются одинаковые названия элементов. Например, вот как выглядит config.h:

enum GameObjectType
{
     NINJA_PLAYER
};

enum GameObjectTypeLocation
{
    NONE,
    MASSAGE_ALL,  // это для ComponentMadiator
    NINJA_PLAYER
};

Однако, когда я пытаюсь скомпилировать проект и вызываю перечисления с соответствующими именами, возникает ошибка компиляции:

m_pNinjaPlayer = (NinjaPlayer*)GameFactory::Instance().getGameObj(GameObjectType::NINJA_PLAYER);
ComponentMadiator::Instance().Register(GameObjectTypeLocation::NINJA_PLAYER, m_pNinjaPlayer);

Ошибка выглядит следующим образом:

error C2365: 'NINJA_PLAYER' : redefinition; previous definition was 'enumerator' (..\Classes\GameFactory.cpp)
2>          d:\dev\cpp\2d\cocos2d-x-3.0\cocos2d-x-3.0\projects\lettersfun\classes\config.h(22) : see declaration of 'NINJA_PLAYER'

Как я могу оставить в config.h несколько перечислений с различными именами, но с одинаковыми названиями элементов?

2 ответ(ов)

0

Проблема заключается в том, что старые перечисления имеют несфокусированное (unscoped) пространство имен. Вы можете избежать этой проблемы (при условии, что ваш компилятор поддерживает соответствующий стандарт C++11) с помощью сфокусированных (scoped) перечислений:

enum class GameObjectType { NINJA_PLAYER };

enum class GameObjectTypeLocation { NONE, MASSAGE_ALL, NINJA_PLAYER };

Альтернативный способ — поместить ваши традиционные перечисления в пространства имен:

namespace foo
{
  enum GameObjectType { NINJA_PLAYER };
} // namespace foo

namespace bar
{
  enum GameObjectTypeLocation { NONE, MASSAGE_ALL, NINJA_PLAYER };
} // namespace bar

В таком случае значения ваших перечислений будут foo::NINJA_PLAYER, bar::NINJA_PLAYER и так далее.

0

Если у вас есть возможность использовать C++11, я бы рекомендовал воспользоваться возможностью enum class, чтобы избежать конфликтов:

enum class GameObjectType
{
    NINJA_PLAYER
};

enum class GameObjectTypeLocation
{
    NONE,
    MASSAGE_ALL,  // это для ComponentMadiator
    NINJA_PLAYER
};

Редактирование: Если у вас нет такой возможности, тогда вам потребуется использовать два разных пространства имен для каждого перечисления.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь