首先看代码示例:
class ClassA {
public:
virtual ~ClassA(){};
virtual void FunctionA(){};
};
class ClassB:public ClassA {
public:
virtual void FunctionB(){};
};
class ClassC : public ClassB {
public:
};
cout << sizeof(ClassA) << sizeof(ClassB) << sizeof(ClassC);//结果是444
struct A{
int a;
char b;
}
struct B:A{
char a;
}
sizeof(sizeof(B));//12,这里并不是8
//这里为了简化,使用struct。在C++中,struct和class除了两点之外完全相同
//1.内部成员默认访问权限不同,struct是public,class是private
//2.派生类默认继承权限不同,struct是public,class是private
struct C {
C(){}
~C(){}
};
sizeof(C);//1,
1.对象内存
解释:
- ClassA在这里等同对一个该类的对象求sizeof
- 无论类内部有多少个虚函数,在类内存内部只存虚函数表的地址(4 bytes)
- member function是不占用空间的,无论你仅在类内部声明,还是在内部实现
- 数据成员按照其类型占用相应的空间(int:4bytes, double:8bytes, 64位环境另当别论。注意,这里的64位不是指操作系统是64位的,而是你的编译环境是多少位的。如VS2013中通过配置管理器可以切换win32和x64)
- 即使ClassB中存在与ClassA中同名的变量,从作用域角度讲,ClassA中的变量会被隐藏,但是这不能掩盖ClassA中的变量被继承的事实,所以ClassA还是会占用两个该变量的内存。
- 注意内存对齐。假如我在ClassA中声明一个
char ch;
(无论在public或者private中)那么结果就会变成888。char类型应该占用一个bytes的空间,但是因为内存对齐,使得申请的空间必须是4bytes的倍数(为了提升访问速度);所以类推,假如在ClassA中声明char ch1; char ch;
那么结果还是888。 - 注意继承。如上条所示,基类的成员变量的访问权限无论是private还是public,派生类都会继承,只不过是能不能访问的问题。
static int a;
这样的a成员是不会占用空间的。const int a = 0
这样的a成员是占用空间的
2.指针地址
ClassC c;
ClassA pa = &c;
ClassB pb = &c;
ClaasC pc = &c;
那么这三个指针所存地址相等。
如图所示,这就是ClassC的内存图,由于ClassC直接继承了ClassB,间接继承了ClassA,所以C中完全包含了A,B。将c对象的地址赋给三个类类型的指针,就是让这三个指针指向自己对象的寻函数表地址,所以都指向了ClassC内存的首地址,所以三个指针的值相同。
假设还是有A,B,C三个类,但是更改继承关系。代码如下:
class ClassA {
public:
virtual ~ClassA(){};
virtual void FunctionA(){};
};
class ClassB {
public:
virtual void FunctionB(){};
};
class ClassC : public ClassA,public ClassB {
public:
};
那么此时三个指针的关系是,pa == pb == pc
如果改变继承顺序,如下:
class ClassC : public ClassB,public ClassA {
public:
};
那么pb == pc
道理相同。
3.enum内存分配
class A {
enum{red,green,yellow};
}
class B {
enum{red, yellow, green}color;
}
sizeof(A);//1,因为enum没有实例化
sizeof(B);//4,相当于一个int
4.union内存分配
union的特点就是内存覆盖,其内部的变量共同使用一块内存,但是每次只能为其中的一个变量赋值。
class A {
union {
char buff[13];
int size;
}
}
class B {
union {
char buff[3];
int size;
}
}
sizeof(A);//16,因为char空间是13bytes大于int的4bytes,所以分配13bytes
sizeof(B);//4,这里char是3bytes,较小,所以分配4bytes