Html> http://www.bkjia.com/kf/201104/88627.html
Http://www.bkjia.com/kf/201104/88628.html
Http://www.bkjia.com/kf/201104/88629.html
After reading the above article, I should be able to answer a question: will the pointer value change after the pointer is forcibly converted to a type?
Answer: sometimes it will. Haoel divides inheritance into five categories, And I mark them again:
No virtual inheritance: single inheritance (1), non-repeated multi-inheritance (2), repeated multi-inheritance (3 );
Virtual inheritance: single inheritance (4), repeated multi-inheritance (5 ).
First, I want to distinguish the two concepts "memory layout of the class (which can calculate the size of the class)" and "memory layout of the class itself (which can calculate the size of the class itself )":
Sizeof (class) = sizeof (class itself) + sizeof (all parent classes ).
The memory layout of the class itself consists of two parts: vptr + member variables. The memory layout of the entire class is to splice the class itself with the memory layout of all its parent classes. Note: for type (1), the entire class has only one vptr, so the memory layout of the parent class is only a member variable.
The splicing rule is: first parent class and then subclass, but the special case is virtual inheritance. in virtual inheritance, it will become "first subclass and then parent class", because the purpose of virtual inheritance is: we share the common things of the parent class.
Therefore, vptr may not always appear at the beginning of the class memory layout. To be precise, it should be at the beginning of the memory layout of each class.
In case of type conversion, for example, to convert from Derived * to Base *, the converted result will be directed to the beginning of the memory layout of the parent class Base ", once the start end is inconsistent with the memory layout start end of the Derived class
After the pointer type is converted, the pointer value changes.
The following is an example:
# Include <iostream>
# Include <string>
# Include <vector>
# Include <map>
# Include <set>
Using namespace std;
Class {
Public:
Virtual ~ A (){};
Int iA;
};
Class A1 {
Public:
Virtual ~ A1 (){};
Int iA1;
};
Class B: public {
Public:
Virtual ~ B (){};
Int iB;
};
Class C: virtual public {
Public:
Virtual ~ C (){};
Int iC;
};
Class D: public A, public A1 {
Public:
Virtual ~ D (){};
Int iD;
};
Int main (int argc, char * argv []) {
A * pa = new B ();
Cout <"B size:" <sizeof (B) <endl;
Cout <"A addr:" <pa <endl;
Cout <"B addr ():" <(B *) pa <endl;
Cout <"B addr dynamic_cast:" <dynamic_cast <B *> (pa) <endl;
Cout <"-------------------------------" <endl;
A * pa2 = new C ();
Cout <"C size:" <sizeof (C) <endl;
Cout <"A addr:" <pa2 <endl;
// Cout <"C addr ():" <(C *) pa2 <endl; // compile error
Cout <"C addr dynamic_cast:" <dynamic_cast <C *> (pa2) <endl;
Cout <"-------------------------------" <endl;
C * pc = dynamic_cast <C *> (pa2 );
Cout <"C addr dynamic_cast:" <pc <endl;
Cout <"A addr ():" <(A *) pc <endl;
Cout <"A addr dynamic_cast:" <dynamic_cast <A *> (pc) <endl;
Cout <"-------------------------------" <endl;
D * pd = new D ();
Cout <"D size:" <sizeof (D) <endl;
Cout <"D addr:" <pd <endl;
Cout <"A addr ():" <(A *) pd <endl;
Cout <"A addr dynamic_cast:" <dynamic_cast <A *> (pd) <endl;
Cout <"A1 addr dynamic_cast:" <dynamic_cast <A1 *> (pd) <endl;
Return 0;
}
Result:
B size: 16
A addr: 0x8a96010
B addr (): 0x8a96010
B addr dynamic_cast: 0x8a96010
-------------------------------
C size: 32
A addr: 0x8a96040
C addr dynamic_cast: 0x8a96030
-------------------------------
C addr dynamic_cast: 0x8a96030
A addr (): 0x8a96040
A addr dynamic_cast: 0x8a96040
-------------------------------
D size: 32
D addr: 0x8a96060
A addr (): 0x8a96060
A addr dynamic_cast: 0x8a96060
A1 addr dynamic_cast: 0x8a96070
Last article
Http://www.bkjia.com/kf/201104/88630.html