C++: Как использовать одни и те же имена членов перечисления в разных перечислениях без ошибки переопределения?
У меня есть файл конфигурации, который я включаю во все свои файлы. В нем содержатся различные перечисления (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 ответ(ов)
Проблема заключается в том, что старые перечисления имеют несфокусированное (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
и так далее.
Если у вас есть возможность использовать C++11, я бы рекомендовал воспользоваться возможностью enum class
, чтобы избежать конфликтов:
enum class GameObjectType
{
NINJA_PLAYER
};
enum class GameObjectTypeLocation
{
NONE,
MASSAGE_ALL, // это для ComponentMadiator
NINJA_PLAYER
};
Редактирование: Если у вас нет такой возможности, тогда вам потребуется использовать два разных пространства имен для каждого перечисления.
Почему enum class считается более безопасным в использовании, чем обычный enum?
Можно ли вручную определить преобразование для класса enum?
Как удалить элемент из std::vector<> по индексу?
`unsigned int` против `size_t`: когда и что использовать?
Какова разница между "new", "malloc" и "calloc" в C++?