c++ - union and the bitfields

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...

 

 

Union

 

 

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

  • it can contain public/private access modifier
  • it can contains constructor or destructor
  • it can conly copy assignment operator or something...

 

 

while what union cannot have:

  • it cannot have member who has contructor, destructor, or copy assignment operator
  • it cannot have static member functions
  • It cannot have reference members such as int &rfi;

 

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;
}

 

Bit fields

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";
	}
}
 

 

 

 

 

 

你可能感兴趣的:(C++)