Thoughts on C ++ enumeration type

xiaoxiao2021-03-06  90

Enumeration type in C inherits in C language. Just like other characteristics from C language inherited, C enumerations also have a disadvantage, which is the most significant thing that is the role domain problem - constant defined in the enumeration type, which belongs to the scope of definition enumeration, not It belongs to this enumeration type. For example, the following example:

ENUM FileAccess {read = 0x1, Write = 0x2,};

FileAccess Access = :: read; // correct fileAccess access = fileaccess :: read; // error

This feature of C enumeration is unacceptable for people who are used to object-oriented and scope concepts. First, FileAccess :: read is clearly more in line with the programmer's intuition, because the above enumeration defines the following definition (actually, the enumeration type in .NET is so real):

Class FileAccess {static const Int = 0x1; static const Int write = 0x2;

Second, this causes us to define an enumeration value of two equally named names in the same scope. That is, the following code is compilation error:

ENUM FileAccess {read = 0x1, Write = 0x2,};

Enum fileshare {read = 0x1, // Redefile WRITE = 0x2, // Refinition};

If this doesn't make you angry, you may haven't worked how much C code :-). In fact, in the latest C 0x standard draft proposal for enumerating the role domain issues, what is the final solution will not be in the prophet, after all, for the use of a wide language like C , any Features' inclusion and modification must be very careful.

Of course, we can use some roundabout way to solve this problem (C can always give us a lot of surprises and accidents). For example, we can put an enumeration value in a structure and use an operator overload to approach the characteristics of enumeration:

Struct FileAccess {ENUM __ENUM {read = 0x1, Write = 0x2}; __enum _value; // enumeration value

FileAccess (int value = 0): _Value ((__ enum) value) {} fileaccess & operator = (int value) {this -> _ value = (__enum) value; return * this;} Operator int () const {return this-> _Value;}};

We can now use this enumeration type in the hope:

FileAccess Access = FileAccess :: read;

And because we provide a conversion operator to the int type, it can be used in places where Int is required, such as the Switch statement:

Switch (Access) {Case FileAccess :: Read: Break; Case FileAccess :: Write: Break;

Of course, we don't want to write such a structure each time. By using the macro, we can easily do this: #define declare_enum (e) / struct e / {/ public: / e (int value = 0): _Value ((__ enum) {/} / e & operator = (int value) {/ this -> _ value = (__enum) value; / return * this; /} / operator int () const {/ return this -> _ value; /} // enum __enum {

#define end_enum () /}; // private: / __enum _value; /};

We can now define the previous enumerations as follows and is not complicated than directly write ENUM.

Declare_enum (FileAccess) Read = 0x1, Write = 0x2, End_enum ()

Declare_enum (fileshare) read = 0x1, Write = 0x2, End_enum ()

转载请注明原文地址:https://www.9cbs.com/read-122470.html

New Post(0)