Why are pA,pB,pC not equal?
考虑以下程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include<iostream> using namespace std; class ClassA { public: virtual ~ClassA(){}; virtual void FunctionA(){}; }; class ClassB { public: virtual void FunctionB(){}; }; class ClassC : public ClassA,public ClassB { }; void main() { ClassC aObject; ClassA* pA = &aObject; ClassB* pB = &aObject; ClassC* pC = &aObject; cout<<"pA ="<<pA<<endl; cout<<"pB ="<<pB<<endl; cout<<"pC ="<<pC<<endl; } |
pa,pb,pc应该相等,但结果是
pA = 0031FD90
pB = 0031FD94
pC = 0031FD90
为什么pb=pa+4?当我改变的时候
1 2 3 4 5 6 7 8 9 10 11 12 | class ClassA { public: virtual ~ClassA(){}; virtual void FunctionA(){}; }; class ClassB { public: virtual void FunctionB(){}; }; |
到
1 2 3 4 5 6 7 | class ClassA { }; class ClassB { }; |
结果是
pA = 0030FAA3
pB = 0030FAA4
pC = 0030FAA3
Pb=Pa+1?
乘法继承的对象有两个合并的子对象。我猜编译器将其中一个指针指向一个内部对象。
这是编译器的实现细节。您之所以打这个案例是因为您的代码中有
想想计算机如何访问
1 | *((int*)pb + 1) // this actually will be assembly generate by compiler |
但是如果
这就是为什么编译器调整pb不等于pa的原因,这将使上述代码工作,这是最简单和最有效的实现方法。
这也解释了为什么
C有两个继承的子对象,因此是A对象和B对象的串联。当你有一个对象C时,它由一个对象A和一个对象B组成。它们不在同一个地址,这就是为什么。所有三个指针都指向同一个对象,但作为不同的超类。编译器为您做出了改变,所以您不必为此担心。
现在。为什么一种情况下4个与另一种情况下1个的差异?在第一种情况下,对于A和B都有虚拟函数,因此每个子对象都必须有指向其vtable(包含解析虚拟函数调用地址的表)的指针。所以在这个例子中,