多重继承:不同的地址相同的地址

时间:2015-07-03 10:18:18

标签: c++

我写了一个示例程序。 如果我打印pa和pb的地址都不同。 你能告诉我为什么会这样吗?

#include<iostream>
using namespace std;
class A {
int x;
};

class B {
int y;
};

class C: public A, public B {
int z;
};

int main()
{
 C c;
 A *pa;
 B *pb;

 pa = &c;
 pb = &c;

cout<<pa<<endl;
cout<<pb<<endl;

}

3 个答案:

答案 0 :(得分:7)

正如Kerrek SB所述,您的示例中的papb实际上并不指向c,而是指向AB < c的em>子对象。

使用多重继承,基类中的数据基本上是一个接一个地堆叠。基类型指针只是偏移到该基类的数据。因此,papb指向c的不同偏移量。

#include<iostream>
using namespace std;

class A {
    public:
    int x;
};

class B {
    public:
    int y;
};

class C: public A, public B {
    public:
    int z;
};

int main()
{
    C c;
    cout << "    &c: " << &c << endl << endl;

    cout << "(A*)&c: " << (A*)&c << endl;
    cout << "(B*)&c: " << (B*)&c << endl << endl;

    cout << "  &c.x: " << &c.x << endl;
    cout << "  &c.y: " << &c.y << endl;
    cout << "  &c.z: " << &c.z << endl << endl;
}

结果:

    &c: 0x7ffdfeb26b20

(A*)&c: 0x7ffdfeb26b20
(B*)&c: 0x7ffdfeb26b24

  &c.x: 0x7ffdfeb26b20
  &c.y: 0x7ffdfeb26b24
  &c.z: 0x7ffdfeb26b28

所以你可以看到C的布局如下:

                  ---------------
0x7ffdfeb26b20    |     x       |     class A data
                  ---------------
0x7ffdfeb26b24    |     y       |     class B data
                  ---------------
0x7ffdfeb26b28    |     z       |     class C data
                  ---------------

如果你在这个例子中添加一些虚拟方法,你会发现子类vtable也会发生同样的事情。

答案 1 :(得分:0)

    ---------   <------pa = &c
   |    x    |
    ---------   <------pb = &c
   |    y    |
    ---------
   |    z    |
    ---------

它取决于类的内存模型,上面是内存中C类的对象

答案 2 :(得分:0)

回到平原的美好时光,有结构。

struct Base{
   int baseMember;
}

struct Child{
   struct Base parent;
   int someMoreMembers;
}

这样,取消引用指向Child的指针就像它是一个基指针一样,会产生一个指向Base的非常好的指针,因为它是第一个成员。 在c ++中,这仍然以相同的方式工作(通常)。但是,如果您现在继承了两个类,则不能将它们作为结构中的第一个成员。因此,C ++通过添加特定基础数据所在的偏移量,将指向基础的指针转换为指向子项的指针。

相关问题