我很想知道類將如何安排在內存中。具有繼承和虛擬功能。繼承類的內存佈局
我知道這不是由C++語言標準定義的。但是,是否有任何簡單的方法可以通過編寫一些測試代碼來找出特定的編譯器如何實現這些說明?
編輯: - 使用下面的一些答案: -
#include <iostream>
using namespace std;
class A {
public:
int a;
virtual void func() {}
};
class B : public A {
public:
int b;
virtual void func() {}
};
class C {
public:
int c;
virtual void func() {}
};
class D : public A, public C {
public:
int d;
virtual void func() {}
};
class E : public C, public A {
public:
int e;
virtual void func() {}
};
class F : public A {
public:
int f;
virtual void func() {}
};
class G : public B, public F {
public:
int g;
virtual void func() {}
};
int main() {
A a; B b; C c; D d; E e; F f; G g;
cout<<"A: "<<(size_t)&a.a-(size_t)&a<<"\n";
cout<<"B: "<<(size_t)&b.a-(size_t)&b<<" "<<(size_t)&b.b-(size_t)&b<<"\n";
cout<<"C: "<<(size_t)&c.c-(size_t)&c<<"\n";
cout<<"D: "<<(size_t)&d.a-(size_t)&d<<" "<<(size_t)&d.c-(size_t)&d<<" "<<(size_t)&d.d- (size_t)&d<<"\n";
cout<<"E: "<<(size_t)&e.a-(size_t)&e<<" "<<(size_t)&e.c-(size_t)&e<<" "<<(size_t)&e.e- (size_t)&e<<"\n";
cout<<"F: "<<(size_t)&f.a-(size_t)&f<<" "<<(size_t)&f.f-(size_t)&f<<"\n";
cout<<"G: "<<(size_t)&g.B::a-(size_t)&g<<" "<<(size_t)&g.F::a-(size_t)&g<<" " <<(size_t)&g.b-(size_t)&g<<" "<<(size_t)&g.f-(size_t)&g<<" "<<(size_t)&g.g-(size_t)&g<<"\n";
}
,輸出是: -
A: 8
B: 8 12
C: 8
D: 8 24 28
E: 24 8 28
F: 8 12
G: 8 24 12 28 32
因此所有的類都在大小爲8的LOC 0獲得了V-PTR D在位置16處有另一個v-ptr。類似地對於E. G在16處似乎也具有v-ptr,但是從我的(有限的)理解中,我會猜測它具有更多。
+1這個示例代碼與我想出的最接近。儘量避免依賴內存佈局。不能保證它在未來版本的編譯器(或者甚至在具有相同編譯器版本的其他上下文中,例如優化)中保持不變。我敢打賭,幾乎總是有更好的方法來解決這個問題。 – Andre 2011-12-29 19:26:02
謝謝。這確實有點幫助。結合你的答案和Azza的... 我也有興趣會發生什麼,如果我們有 A類; B類; B類; C類:公共A,公共B; 這似乎給出了有多個vtable指針的結果。 A的數據成員似乎先於B. – owagh 2011-12-29 19:38:26
我從來沒有處理過多重繼承。但你仍然可以嘗試看看補償顯示的是什麼。我真的不知道多重繼承如何在底下工作。 – Mysticial 2011-12-29 19:40:57