Разделение Enums от определений классов с использованием пространств имен в С++?

Я работаю с унаследованным классом, который выглядит так:

class A
{
    enum Flags { One = 1, Two = 2 };
};

Я хотел бы вытащить все перечисления в новое пространство имен, определенное в новом заголовке:

// flags.h

namespace flags {

enum Flags { One = 1, Two = 2 };

};

Затем верните эти перечисления обратно в класс, чтобы я мог включить только flags.h в заголовки, которым требуются только эти значения (а не все определение класса):

// a.h

#include "flags.h"

class A
{
    using namespace flags;
};

Как я должен это делать?


person Dan    schedule 16.11.2009    source источник
comment
Можете ли вы пояснить, что у вас работает, а что нет, и как вы хотите использовать это в коде? Почему бы не поместить перечисления в суперкласс?   -  person Björn Pollex    schedule 16.11.2009


Ответы (3)


Директива using недопустима в области класса. Вместо пространства имен вы можете определить класс, а затем наследовать от него:

struct flags {
    enum Flags { One=1, Two=2 };
};

class A : public flags { ... };

Но мне это кажется неправильным использованием наследства, если честно. В качестве альтернативы вы можете стиснуть зубы и использовать пространство имен без "импорта" имен в класс A.

person sellibitze    schedule 16.11.2009
comment
Укусить пулю - лучший вариант, хотя я все же предпочитаю struct инкапсуляцию, чем namespace, потому что структура взаимодействует с шаблонами так, как пространство имен этого не делает. - person Matthieu M.; 16.11.2009
comment
как может пространство имен стиля struct когда-либо быть преимуществом с шаблонами? Как видите, структура просто позволяет вам делать одно и то же двумя способами. шаблон из пространства имен структуры или типа перечисления. В то время как более стандартное использование пространства имен допускает только одно. Больше способов сделать то же самое желательно только при написании Perl. - person deft_code; 16.11.2009

Вы не можете сделать их все видимыми в классе, не вытягивая значения отдельно через объявления using.

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

struct Holder {
   enum E { a };
protected:
   Holder() {}
   ~Holder() {}
};

class User : public Holder 
{
public:
   void f() { /* a is visible here */ }
};

void f() { /* User::a is visible here */ }
person Georg Fritzsche    schedule 16.11.2009
comment
Обнаружено неправильное использование наследования... не могли бы вы хотя бы указать конструкторы и деструкторы F protected? - person Matthieu M.; 16.11.2009
comment
Вы имеете в виду Holder? Дело принято. - person Georg Fritzsche; 16.11.2009

person    schedule
comment
Обнаружено неправильное использование наследования... не могли бы вы хотя бы указать конструкторы и деструкторы F protected? - person Matthieu M.; 16.11.2009