предварительное объявление перечисления в базовом классе, определение в производном классе

Итак, я пытаюсь определить перечисление в производном классе, где объявление находится в базовом классе. Это выглядит примерно так:

class A {
    public:
    enum class E;
    virtual int foo () = 0;
};

class B : public A {
    public:
    enum class E { C, D };
    int foo () {
        E e = E::C;
        return 0;
    }
};

int main() {
    B b;
    A *a = &b;
    a->foo();
}

Это будет работать (компилятор gcc 4.8, команда компиляции: g++ -std=c++11...), однако мне было интересно, есть ли лучший способ сделать это, чтобы мне не приходилось каждый раз писать E:: Я должен использовать перечисление.

edit: я ошибочно подумал, что это работает, однако на самом деле это не прямое объявление, а два разных класса enum A::E и B::E


person burnedWood    schedule 15.11.2015    source источник
comment
что мне не нужно писать E:: каждый раз, когда мне нужно использовать перечисление -- тогда используйте старый enum вместо enum class.   -  person GingerPlusPlus    schedule 15.11.2015
comment
Зачем вам нужна декларация в базовом классе?   -  person GingerPlusPlus    schedule 15.11.2015
comment
этот форвард хоть что-нибудь делает? вы заявляете, что есть A::E, который вы не используете. это, вероятно, не связано с B::E, который вы затем определяете   -  person sp2danny    schedule 15.11.2015
comment
@ sp2danny да, похоже, ты прав. Какими способами можно объявить перечисление в базовом классе и определить его в производном классе?   -  person burnedWood    schedule 15.11.2015
comment
@GingerPlusPlus Мне это нужно, чтобы другие производные классы могли определять E по-своему.   -  person burnedWood    schedule 15.11.2015
comment
нет, насколько я знаю. Типы не виртуальные.   -  person sp2danny    schedule 15.11.2015
comment
@burnedWood: но... почему? Зачем вам нужен виртуальный enum?   -  person GingerPlusPlus    schedule 15.11.2015


Ответы (2)


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

Это не связано с предварительным объявлением. Вы должны написать E::, потому что вы используете enum class.
Если вы не хотите этого, используйте вместо этого старое enum:

class B : public A {
    public:
    enum E { C, D };
    // ...
};
person GingerPlusPlus    schedule 15.11.2015
comment
Однако спасибо за ваш ответ, как я могу объявить старое перечисление? Мне нужно предварительное объявление, чтобы другие производные классы могли определять E так, как им нравится. - person burnedWood; 15.11.2015

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

Итак, если у вас есть два следующих класса,

class A {

  public:

    enum class E {
      X,
      Y
    };

 };

class B : public A {

  public:

    enum class E {
      V,
      W
    };

 };

Типы A::E и B::E являются разными типами. Независимо от иерархии классов, между ними нет никакой связи.

person Jason    schedule 15.11.2015