In C ++, pointer type conversion often happens. For example, you can convert a pointer from a derived class to a base class pointer and a base class pointer to a derived class pointer. A pointer is essentially an integer used to record the address numbers in the virtual memory space of a process. The pointer type determines how the compiler interprets the memory space it points.
Based on the above understanding, we can draw a conclusion that the type conversion of pointers in C ++ will not change the pointer value, it only changes the pointer type (that is, it changes the compiler's interpretation of the pointer to the memory), but this conclusion is not true under the Multi-inheritance of c ++.
See the following section.Code:
1 # Include <iostream> 2 Using Namespace STD; 3 4 Class Cbasea 5 { 6 Public : 7 Char M_a [ 32 ]; 8 }; 9 10 Class Cbaseb 11 { 12 Public : 13 Char M_ B [ 64 ]; 14 }; 15 16 Class Cderive: Public Cbasea, Public Cbaseb 17 { 18 Public : 19 Char M_d [ 128 ]; 20 }; 21 22 23 Int Main () 24 { 25 Auto Pd = New Cderive; 26 Auto Pa = (cbasea * ) PD; 27 Auto Pb = (cbaseb * ) PD; 28 29 Cout <Pa < ' \ N ' <Pb < ' \ N ' <PD < Endl; 30 Cout <(Pd = Pb) <Endl; 31 }
The output of this Code is:
0x9f1080
0x9f10a0
0x9f1080
1
It can be seen that the new memory pointer pointing to the same stack changes after the type conversion. The reason is to start with the memory layout inherited by multiple operators in C ++.
New cderive; after execution, the generated memory layout is as follows:
At the same time, we noticed that the pointer difference between PB and PD is exactly 32 bytes of memory occupied by cbasea, while PA and PD both point to the same address segment. This is because,To convert a pointer from a derived class to a base class pointer, the compiler will offset the pointer value to the starting position of the base class in the object memory.
But why is C ++ designed like this?
Imagine that in the above scenario, if both Pb and PA point to the first address of the object, then when the Pb pointer is used to locate the member variable m_ B of cbaseb, the compiler should offset the Pb pointer to 32 bytes to skip the memory section of cbasea. If the Pb pointer generates auto Pb = new cbaseb; then when the Pb pointer is used to locate the member variable m_ B of cbaseb, the offset should be 0.
The key is that for a pointer, the compiler does not care about and cannot know the source of the pointer (in an extreme case, the pointer is transmitted from other modules ), instead, it is regarded as an integer with a pointer type. Therefore, for the cbaseb type pointer, when the member variable m_ B of cbaseb is obtained, the offset should be 0. This is a unified decision through the cbaseb class declaration.
Here, we should be clear why the pointer addresses of PD and Pb are different, but why is the output of the following code 1?
Cout <(Pd = Pb) <Endl;
Output 1 indicates that PD and Pb are equal, but we just showed that the addresses of PD and Pb are 32 bytes different.
In fact, this is also the difference that the compiler shields everyone from. When the compiler finds a pointer pointing to a derived class and a pointer pointing to a base class of =, the pointer is automatically raised as an implicit type and the pointer difference caused by multiple inheritance is blocked. Because the two pointers are compared, the purpose is to determine whether the two pointers point to the same memory object instance. In the above scenario, although the pointer values of Pd and Pb are different, but they actually point to the same memory object (New cderive; generated Memory Object), so the compiler inserts a script here, so that we can enjoy the upper-layer semantics of the = operation.
From: http://www.cnblogs.com/itZhy/archive/2012/10/08/2713367.html