Recently saw a more interesting method of storing data, using the class, but not using member variables to store, so called Pseudo class (Fake Class) mode, think the idea is very interesting, take to share. Overall Thinking
The idea is quite unique, and we all know that if there are no member variables in the class, there is no virtual function, is also not a subclass of virtual inheritance, only a non-virtual member function, then the class can be considered an empty class, that is, the class size is 0 (this type of class in the actual compiler size is typically 1, in order to uniquely identify the object). Since there is no member variable and how to store specific information, the answer is to use this pointer to the corresponding memory, through the logical operation, access to the corresponding property values. Simple example:
typedef unsigned long int uint32;
typedef unsigned char uint8;
Mask code:0 bit of 1, 1 bit of 1, 2 bits of 1....N bits of 1 const uint32 mask[] = {0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007F, 0X000000FF, 0X000001FF, 0X000003FF, 0x000007ff, 0x00000fff, 0x00001fff, 0X00003FFF, 0x 00007FFF, 0x0000FFFF, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0X000FFFFF, 0x00
1FFFFF, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0X07FFFFFF, 0X0FFFFFFF,
0x1FFFFFFF, 0x3fffffff, 0x7fffffff, 0xFFFFFFFF}; Reset n bit of Val begin at Startbit #define Reset_bits (Val, Startbit, N) (val) &= ~ (mask[n]<< (startbit))//g Et specific value of several certain bits #define Extract_bits (val, Startbit, N) ((val) >> (startbit)) & Mask[n ] class FaKeclass {public:enum//attribute Info:index of Byte, start bit of byte and occupied bits of attribute. {//attribute A attr_a_byte = 0, Attr_a_bit_in_byte = 0, Attr_a_bit_len = 3,//at
Tribute B Attr_b_byte = 1, Attr_b_bit_in_byte = 4, Attr_b_bit_len = 4,}; attribute A void Setattra (UInt32 roadclass) {reset_bits ((uint8*) this) [Attr_a_byte], \ Attr
_a_bit_in_byte, \ Attr_a_bit_len); ((uint8*) this)
[Attr_a_byte] |= roadclass << attr_a_bit_in_byte;
} void Resetattra () {reset_bits ((uint8*) this) [Attr_a_byte], \ Attr_a_bit_in_byte, \
Attr_a_bit_len); } uint32 Getattra () const {return extract_bits ((uint8*) this) [Attr_a_byte], \ Attr_a_bit_in_
BYTE, \ Attr_a_bit_len); }//attribute B void Setattrb (UInt32 roadclass) {reset_bits ((uint8*) this) [Attr_b_byte], \ Attr_b_bit_in_byte, \ Attr_b_bit_len); ((uint8*) this)
[Attr_b_byte] |= roadclass << attr_b_bit_in_byte;
} void Resetattrb () {reset_bits ((uint8*) this) [Attr_b_byte], \ Attr_b_bit_in_byte, \
Attr_b_bit_len); } uint32 GETATTRB () const {return extract_bits ((uint8*) this) [Attr_b_byte], \ Attr_b_bit_in_
BYTE, \ Attr_b_bit_len);
}
}; int main () {const unsigned int mem_size = 2;//need to byte to store attribute A and B fakeclass* fakeclass = (Fak
eclass*) New Uint8[mem_size];
memset (fakeclass, 0, mem_size);
Fakeclass->setattra (7);//set A UInt32 Attra = Fakeclass->getattra ();
FAKECLASS->SETATTRB//set B UInt32 attrb = FAKECLASS->GETATTRB ();
Fakeclass->resetattra ();//reset fakeclass->resetattrb ();
return 0; }
This code means that the class Fakeclass uses two bytes to store A and B two properties, and a property is located in a low byte (attr_a_byte = 0), which begins with the first bit (bit) (Attr_a_bit_in_byte = 0), Property A requires three bytes to store (Attr_a_bit_len = 3), Value range: 0~7 (binary 0000~0111), similar, for attribute B, located in high byte, starting at the fifth bit of the byte, the length occupies 4 bytes, the value range: 0~15 (binary 0000~ 1111), member functions manipulate these corresponding bits through the mask mask defined above to achieve the purpose of storing, reading and resetting zeros.
The main mystery of this section of the code in this sentence:
((uint8*) this) [...] ...
The this pointer is treated as the first address of the array because there is no member variable in the class, so the this pointer points directly to the allocated array space:
fakeclass* Fakeclass = (fakeclass*) new uint8[mem_size];
look at the actual running results:
Pointer Fakeclass address is: 0x01468c88, point to two bytes of space, after Memset, initialized to 0
After Fakeclass->setattra (7), the property A is set to 7, that is, the lower 8 digits, the first to the third digit all to 1, at this point the Fakeclass point to the address value is: 0000 0111-0000 0000
Similarly, when FAKECLASS->SETATTRB (15), attribute B corresponds to the bit: High byte fifth to eighth digits all 1, at this point the Fakeclass point to the address value is: 0000 0111-1111 0000
Finally, after the Reset,a and B properties are emptied:
Because property A and property B have length limits, once the value passed in exceeds the maximum value, the unexpected value, such as the bit digit 3 of attribute A, is 7, and if you pass in 9 with a low byte value of 0000 1000, the corresponding property a three is: 000, so at this point a value of 0 is taken, Same B incoming 22 o'clock, the high byte is: 0110 1000, the corresponding property B four bits are: 0110, at this time the B value is 6:
Summary
Personal feeling this method of storing properties is more suitable for scenarios where memory usage is strictly restricted, such as embedded devices, on-board devices, etc., to ensure that no space is wasted.
Note: There are several bits in the previous example that do not store content, because this example is for demonstration purposes only, the actual project in order to maximize the use of memory, will be strictly filled with each.