2017-10-02 1 views
0

Je reçois une erreur avec un programme. Évidemment, il me manque quelque chose à propos de la syntaxe. L'extrait de code C++ ci-dessous est le plus petit qui génère l'erreur.Syntaxe d'accès à Enum à partir de la classe parente

#include <iostream> 
using namespace std; 

class Parent 
{ 
    public: 
    enum MyEnum { 
     Value1, 
     Value2, 
     Value3 
    }; 

    MyEnum* set; 
}; 

class Child: public Parent 
{ 
    public: 
    Child() 
    { 
     set = new MyEnum[5]; 
     set[0]=MyEnum.Value1;//<--Something wrong here 
     set[1]=MyEnum.Value2;//<--Something wrong here 
     set[2]=MyEnum.Value3;//<--Something wrong here 
     set[3]=MyEnum.Value2;//<--Something wrong here 
     set[4]=MyEnum.Value1;//<--Something wrong here 
    } 

    void Write() 
    { 
     for(int i=0;i<5;i++) 
     { 
      cout<< "This is " << i << ": " << set[i]; 
     } 
    } 
}; 

int main() { 
    Child c; 
    c.Write(); 

    return 0; 
} 

L'erreur a quelque chose à voir avec la syntaxe indiquée.

expected primary-expression before ‘.’ token 

J'ai essayé Parent.MyEnum.Value1, Parent :: MyEnum.Value1, etc. rien ne semble avoir raison. Comment devrais-je faire référence aux valeurs spécifiques dans la classe parente?

+0

'MyEnum.Value1; // <- Quelque chose ne va pas ici' - La syntaxe. C'est juste "Value1" si vous avez une énumération régulière. [Choisissez un bon livre] (https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), il vous le dira et plus encore. – StoryTeller

+1

Qu'en est-il des gens qu'ils aiment supposer que quelqu'un est un novice ou mal lu parce qu'ils ont une question. Comme je n'ai pas trois livres en C++ à portée de main. Merci pour ça. Pour en revenir à la question, POURQUOI cette syntaxe est-elle acceptable? Et qu'est-ce qu'un "enum" régulier? Existe-t-il un autre type d'énumération? – BSD

+2

Quoi, vos 3 livres ne vous ont pas parlé d'énumérations étendues et non délimitées? – StoryTeller

Répondre

3

énumérations ne nécessitent pas de qualification pour leurs valeurs, ce qui signifie que vous devez y accéder comme ceci:

set[0] = Parent::Value1; 

Si vous souhaitez appliquer la qualification, vous pouvez utiliser fortement typé énumérations. Il ressemble à ceci:

enum struct MyEnum { 
    Value1, 
    Value2, 
    Value3 
}; 

set[0] = Parent::MyEnum::Value1; 

Mais vous devez les imprimer à l'aide d'une distribution explicite, par exemple:

cout << static_cast<int>(set[0]) << endl; 
1

Un enum, comme un class, définit un champ. Une énumération régulière que vous utilisez met ses noms d'énumérateur à la fois dans sa propre portée et dans sa portée. Puisqu'il s'agit d'une résolution d'étendue, et non d'un accès membre, vous utilisez :: au lieu de .. Par conséquent, vous pouvez utiliser Parent::Value1, Value1 (car public et protected les noms de Parent sont visibles dans Child) ou Parent::MyEnum::Value1 ou MyEnum::Value1. Si vous souhaitez interdire la première ou les deux options, vous devez utiliser enum class au lieu de simplement enum.

+0

Seules les énumérations délimitées définissent une étendue. C'est pourquoi ils ont été ajoutés à la langue. Pour les énumérations non délimitées 'MyEnum :: Value1' fonctionne seulement comme une extension sur MSVC. – StoryTeller

+0

@StoryTeller Je n'ai rien trouvé qui le permette, mais il [fonctionne en gcc] (https://godbolt.org/g/3jtSkC) et [clang] (https://godbolt.org/g/x1QukD) avec '-std = C++ 11 -Wall -Wextra -pedantic'. Si vous n'incluez pas le drapeau '-std',' clang' dit qu'il vient de C++ 11. –

+0

@StoryTeller Selon un commentaire de code dans le dernier exemple [ici] (http://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration), cela fonctionne. Je n'ai pas encore regardé la norme, mais cela correspond à ce que les compilateurs disent, donc je le crois. –