Pointer drift caused by multiple inheritance in C ++

Source: Internet
Author: User
Tags multiple inheritance in c

Recently we encountered a strange problem in our work. We finally decided that the pointer drift caused by multi-inheritance was related to the C ++ object model. The diagram is as follows:

Class {...};
Class B {...};
Class AB: Public B, public {...}
...
AB * PAB = new AB ();
A * pA = (A *) PAB;
B * pb = (B *) PAB;

At this time, you find that the values of PA and Pb are different! One of them is equal to PAB, And the other generates an offset. If we change the order of A and B in the AB statement, the pointer that generates the offset will change to another one.

To make sure that this is the reason for the compiler to convert, use the void pointer to fool the compiler:
Void * Pv = (void *) PAB;
Pa = (A *) PV;

At this time, the value of PA is equal to that of PAB, But it points to the wrong place. The transition from PAB to PA depends on the path selection, which is not reassuring. I still don't know if it will make an error if I put the pointer into the container and then retrieve it. Of course, the above uses forced type conversion, in goodProgram. If there is only implicit conversion, the correct result is displayed:

STD: vector <A *> V;
// Implicit type conversion
V. insert (V. Begin (), PAB );
Void * Pv = V [0];
Pa = (A *) PV;

The following program is compiled using cygwin/g ++ B:

# Include <stdio. h>
# Include <vector>

Class
{
Public:
Int;
};
Class B
{
Public:
Int B;
};
Class AB: Public B, public
{
Public:
Int AB;
};

Int main (INT argc, char ** argv)
{
AB * PAB = new AB ();
Pab-> AB = 1;
Pab-> B = 2;
Pab-> A = 3;

A * pA = (A *) PAB;
B * pb = (B *) PAB;

Printf ("AB: % P \ n "\
"A: % P \ n "\
"B: % P \ n ",
PAB, Pa, Pb );

STD: vector <A *> V;
// Implicit type conversion
V. insert (V. Begin (), PAB );
Void * Pv = V [0];
Pa = (A *) PV;
Printf ("PV is % P \ NPA is % P \ npab % s PV \ n", PV, Pa, (PAB = PV )? "= ":"! = ");

Printf ("A. A is % d \ n", pa-> );
// Forced type conversion
Pv = (void *) PAB;
Pa = (A *) PV;
Printf ("Now A. A is % d \ n", pa-> );
}

Running result:
AB: 0x6b01f0
A: 0x6b01f4
B: 0x6b01f0
PV is 0x6b01f4
Pa is 0x6b01f4
Pab! = PV
A. A is 3
Now a. A is 2

Absurd Published on 11:48:00 IP: 211.161.63. * This is a compiler feature. com uses this feature to get the offset of a subclass instance (COM subject: inttable. h ):
# Define base_offset (classname, basename )\
(DWORD (static_cast <basename *> (reinterpret_cast <classname *> (0x10000000)-0x10000000) Reprinted from: http://www.yuanma.org/data/2006/0716/article_1143.htm
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.