内存布局示例
class Base {
public:
int method(int p);
protected:
int foo;
private:
int pbfoo;
};
struct Point {
double cx, cy;
};
class Derived : public Base {
public:
int method(int p);
protected:
int bar, baz;
Point a_point;
char c;
};
int main(int argc, char** argv) {
return sizeof(Derived);
}
要查看布局,请运行clang -cc1 -fdump-record-layouts myfile.cpp。它将为每个定义的类和结构生成一个单独的报告,但最有趣的一个是Derived类:
*** Dumping AST Record Layout 0 | class Base 0 | int foo 4 | int pbfoo | [sizeof=8, dsize=8, align=4, | nvsize=8, nvalign=4] *** Dumping AST Record Layout 0 | struct Point 0 | double cx 8 | double cy | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Derived 0 | class Base (base) 0 | int foo 4 | int pbfoo 8 | int bar 12 | int baz 16 | struct Point a_point 16 | double cx 24 | double cy 32 | char c | [sizeof=40, dsize=33, align=8, | nvsize=33, nvalign=8]
基类包含virtual函数
class Base {
public:
int method(int p);
virtual int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
struct Point {
double cx, cy;
};
class Derived : public Base {
public:
int method(int p);
protected:
int bar, baz;
Point a_point;
char c;
};
int main(int argc, char** argv) {
return sizeof(Derived);
}
输出:
*** Dumping AST Record Layout 0 | class Base 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | struct Point 0 | double cx 8 | double cy | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Derived 0 | class Base (primary base) 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo 16 | int bar 20 | int baz 24 | struct Point a_point 24 | double cx 32 | double cy 40 | char c | [sizeof=48, dsize=41, align=8, | nvsize=41, nvalign=8]
派生类包含virtual函数
class Base {
public:
int method(int p);
int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
struct Point {
double cx, cy;
};
class Derived : public Base {
public:
int method(int p);
virtual int vbfunc();
virtual int vdfunc();
protected:
int bar, baz;
Point a_point;
char c;
};
int main(int argc, char** argv) {
return sizeof(Derived);
}
输出:
*** Dumping AST Record Layout 0 | class Base 0 | int foo 4 | int pbfoo | [sizeof=8, dsize=8, align=4, | nvsize=8, nvalign=4] *** Dumping AST Record Layout 0 | struct Point 0 | double cx 8 | double cy | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Derived 0 | (Derived vtable pointer) 8 | class Base (base) 8 | int foo 12 | int pbfoo 16 | int bar 20 | int baz 24 | struct Point a_point 24 | double cx 32 | double cy 40 | char c | [sizeof=48, dsize=41, align=8, | nvsize=41, nvalign=8]
基类和派生类都包含virtual函数
class Base {
public:
int method(int p);
virtual int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
struct Point {
double cx, cy;
};
class Derived : public Base {
public:
int method(int p);
virtual int vbfunc();
virtual int vdfunc();
protected:
int bar, baz;
Point a_point;
char c;
};
int main(int argc, char** argv) {
return sizeof(Derived);
}
输出:
*** Dumping AST Record Layout 0 | class Base 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | struct Point 0 | double cx 8 | double cy | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Derived 0 | class Base (primary base) 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo 16 | int bar 20 | int baz 24 | struct Point a_point 24 | double cx 32 | double cy 40 | char c | [sizeof=48, dsize=41, align=8, | nvsize=41, nvalign=8]
virtual继承
class Base {
public:
int method(int p);
virtual int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
class VBase {
public:
int method(int p);
virtual int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
struct Point {
double cx, cy;
};
class Derived : public virtual VBase, public Base {
public:
int method(int p);
virtual int vbfunc();
virtual int vdfunc();
protected:
int bar, baz;
Point a_point;
char c;
};
int main(int argc, char** argv) {
return sizeof(Derived);
}
输出:
*** Dumping AST Record Layout 0 | class VBase 0 | (VBase vtable pointer) 8 | int foo 12 | int pbfoo | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Base 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | struct Point 0 | double cx 8 | double cy | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Derived 0 | class Base (primary base) 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo 16 | int bar 20 | int baz 24 | struct Point a_point 24 | double cx 32 | double cy 40 | char c 48 | class VBase (virtual base) 48 | (VBase vtable pointer) 56 | int foo 60 | int pbfoo | [sizeof=64, dsize=64, align=8, | nvsize=41, nvalign=8]
virtaul继承2
class VBase {
public:
int method(int p);
virtual int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
class Base : public virtual VBase {
public:
int method(int p);
virtual int vbfunc();
protected:
int foo;
private:
int pbfoo;
};
struct Point {
double cx, cy;
};
class Derived : public virtual VBase, public Base {
public:
int method(int p);
virtual int vbfunc();
virtual int vdfunc();
protected:
int bar, baz;
Point a_point;
char c;
};
int main(int argc, char** argv) {
return sizeof(Derived);
}
输出:
*** Dumping AST Record Layout 0 | class VBase 0 | (VBase vtable pointer) 8 | int foo 12 | int pbfoo | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Base 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo 16 | class VBase (virtual base) 16 | (VBase vtable pointer) 24 | int foo 28 | int pbfoo | [sizeof=32, dsize=32, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | struct Point 0 | double cx 8 | double cy | [sizeof=16, dsize=16, align=8, | nvsize=16, nvalign=8] *** Dumping AST Record Layout 0 | class Derived 0 | class Base (primary base) 0 | (Base vtable pointer) 8 | int foo 12 | int pbfoo 16 | int bar 20 | int baz 24 | struct Point a_point 24 | double cx 32 | double cy 40 | char c 48 | class VBase (virtual base) 48 | (VBase vtable pointer) 56 | int foo 60 | int pbfoo | [sizeof=64, dsize=64, align=8, | nvsize=41, nvalign=8]