У меня есть.h файл:
class MyClass
{
enum MyTypes{
type1 = 1,
type2 = 2,
type3 = 3,
// and so on
};
};
Можно ли отделить "= значение" от этого объявления до другого места, а именно связанного файла cpp? Причина в том, что это перечисление имеет странные значения, предоставляемые удаленным сервером, который я не контролирую. Я хотел бы удалить его из глаз клиента.
Я хотел бы иметь.cpp файл с
enum MyClass::MyTypes{
type1 = 12,
type2 = 14,
type3 = 28,
// and so on
};
Но компилятор говорит, что я переопределяю MyTypes, что верно.
Для подтверждения Криса комментария c++ 11 позволяет переадресовать объявить перечисления. Следующий код не будет выполнен в c++ 03, но скомпилирован в c++ 11:
struct S {
enum E : int;
};
enum S::E : int {
a,b,c
};
N2764, а также Forward, объявляющие перечисление в c++, более подробно, но:
Причина, по которой перечисление не может быть объявлено вперед, заключается в том, что, не зная значений, компилятор не может знать хранилище, необходимое для переменной enum.
Это необязательно для enum class
поскольку по умолчанию используется тип int.
"Обходной путь" - это переслать декларацию структуры, содержащей перечисление. Кредит идет к Лешеку Свирски. Примечание: переменные макросы являются расширением gcc в c++ 03.
#define ENUM_CLASS(NAME, TYPE, VALUES...) \
struct NAME { \
enum e { VALUES }; \
explicit NAME(TYPE v) : val(v) {} \
NAME(e v) : val(v) {} \
operator e() const { return e(val); } \
private:\
TYPE val; \
}
struct Enum;
void f(Enum e);
ENUM_CLASS(Enum, int,
VALUE,
ANOTHER_VALUE
);
void f (Enum e)
{
switch(e)
{
case Enum::VALUE:
std::cout << "VALUE" << std::endl;
return;
case Enum::ANOTHER_VALUE:
std::cout << "ANOTHER_VALUE" << std::endl;
return;
}
}
f(Enum::ANOTHER_VALUE);
Я не думаю, что это возможно с помощью enum
. Я могу думать о нескольких возможных решениях:
Используйте глобальные статические переменные. Это означает, что вам нужно только объявить переменные в файле.h, и вы можете определить и инициализировать их в файле.cpp.
Создайте класс с методами getter, которые возвращают значения.
Создайте один метод getter, который возвращает "реальные" значения на основе "фиктивного" перечисления.
Вы можете переслать объявление enum
:
class MyClass
{
enum MyTypes;
};
с последующим
enum MyClass::MyTypes
{
type1 = 12, // ...
};
Никто, кроме вашего класса, не сможет использовать эти имена, потому что они еще не определены; учитывая, что enum
в любом случае является private
в этом примере, это должно быть хорошо.