2014-01-30 4 views
0

У меня есть файл .h:Можно ли отделить значения enum от декларации?

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, что это правда.

+0

Зачем ставить его в .cpp файл разрешает проблему с удаленного сервера? – billz

ответ

1

Вы можете переадресовать объявить enum:

class MyClass 
{ 
    enum MyTypes; 
}; 

следует

enum MyClass::MyTypes 
{ 
    type1 = 12, // ... 
}; 

Нет одного, но ваш класс будет иметь возможность использовать эти имена, потому что они еще не определены; учитывая, что enum в этом случае равно private, это должно быть хорошо.

+1

Не уверен, что внутри классов, но вне классов, вам нужно указать базовый тип. Изменить: Да, попробуйте удалить базовый тип из [здесь] (http://coliru.stacked-crooked.com/a/98b3676b2f16ed1f). – chris

+0

@chris В этом ответе можно найти некоторое обоснование [здесь] (http://stackoverflow.com/a/72599/1508519). Кажется, вы уже знаете об этом, хотя, учитывая ваш пример. –

+0

Но тогда пользователи, включая h-файл, содержащий MyClass, не будут знать о перечислении. Это побеждает то, что я пытаюсь сделать здесь – Eric

3

Невозможно это можно использовать enum. Я могу представить несколько возможных решений:

  1. Использовать глобальные статические переменные. Это означает, что вам нужно только объявить переменные в файле .h, и вы можете определить и инициализировать их в файле .cpp.

  2. Создайте класс с методами getter, которые возвращают значения.

  3. Создайте один метод getter, который возвращает «реальные» значения на основе «фиктивного» перечисления.

4

Для подтверждения комментария chris «s, C++ 11 позволяет переадресовать объявить перечисления. Следующий код потерпит неудачу в C++ 03, но компилировать в C++ 11:

struct S { 
    enum E : int; 
}; 

enum S::E : int { 
    a,b,c 
}; 

N2764, а также Forward declaring an enum in c++ вдаваться в подробности, но:

Причина перечисление не может быть объявленным вперед, заключается в том, что, не зная значений , компилятор не может знать память, необходимую для переменной enum .

Это необязательно для enum class, поскольку по умолчанию используется тип int.


«Обходной путь» заключается в том, чтобы переслать объявление структуры, содержащей перечисление. Кредит составляет Leszek Swirski. Примечание: переменные макросы являются расширением 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); 
+0

Спасибо за разъяснение. Однако я не могу использовать C++ 11 из-за ограничений платформы. – Eric

+0

@ Эрик Я сделал редактирование. –

Смежные вопросы