C++ has some good compatability with the C language, which offers good support for low-level machine level programming construct, the union and the bitfield are two examples of such...
the union is a special kind of class, the data members inside the union are stored in memory in such a way that they overlap with each other.
that's said, it means the union should have the following.
what a union can have
while what union cannot have:
First, let's suppose that we have a lex parser, which can pase
int i = 0;
to a sequence of symbols
Type, ID, Assign, Constant, Semicolon;
so, we can define a enum to represent each type of the symbols.
enum TokenKind { Type, ID, Assign, Constant, Semicolon };
and we have to define a union that can reprent the values of the datas of the symbols.
union TokenValue { public : TokenValue() {} TokenValue(int ix_ ): _ival(ix_) {} TokenValue(char ch_) : _cval(ch_) {} TokenValue(char * sval_): _sval(sval_) {} TokenValue(double dval_) : _dval(dval_) {} int ival() { return _ival; } char cval() { return _cval; } char * sval() { return _sval;} double dval() { return _dval;} char _cval; int _ival; char *_sval; double _dval; }; class Token { public: TokenKind tok; TokenValue val; };
As you can see, the union type TokenValue has access modifier, it has the member functions, and it has constructors.
To use the union, we can define a class which has both the union as the value and a enum as the indicator which tracks the type of value stored inside the union.
here is one simple code .
TokenKind parse() { return ID; } /* * below shows you how to use the union, it is a best practise to keep a token kind to keep track of what type of data is stored in the union type. */ int lex() { Token curToken; char * curString; int curIVal; switch (parse()) { case ID: curToken.tok = ID; curToken.val._sval = curString; break; case Constant: curToken.tok = Constant; curToken.val._ival = curIVal; break; default: break; } return 0; }
A specied class data member , referenced to as bit-fields, can be declared to hold a specified number of bits. A bit fields must have an integral data type, It can either signed or unsigned.
/** *bit fiels * bit fiels is a space saving member */ typedef unsigned int Bit; class File { public: Bit mode: 2; Bit modified : 1; Bit prot_owner : 3; Bit prot_group : 3; Bit prot_world : 3; void write(); void close(); }; void File:: write() { modified = 1; } void File::close() { if (modified) { // ... save contents } } enum { READ = 01, WRITE = 02 } ; int test_bitfields() { File myfile ; myfile.mode != READ; if (myfile.mode & READ) { cout << "myfile.mode is set to READ \n"; } }