类的大小:
类的存储区域可划分为:公共区域(静态成员、成员函数)、成员数据
公共区域(静态成员:所有成员均摊静态成员的大小后约等于没有、成员函数)
我们可以计算的为普通数据成员的大小;
代码举例:
1、普通类(静态成员、成员函数、成员数据)
class A //大小: 每个对象的数据是单独的(静态数据除外),方法占用的空是公用的,不算
{
public:
void show()const //函数不算大小
{
cout << "m_a:" << m_a << ",m_b:" << m_b << endl;
}
void seta(int a) //函数不算大小
{
m_a = a;
}
void setb(int b) //函数不算大小
{
m_b = b;
}
private:
int m_a;
int m_b;
static int m_c; //静态成员不算类大小
};
int A::m_c = 0;
int main()
{
cout << "占有字节大小为:"<<sizeof(class A) << endl;
}
大小为两个整型成员变量所占用的,静态成员、成员函数不算在内
2、空类(空结构体)
注意:当此类为空类时,该类占有一个字节大小
class C //空类占多大? 1字节 .
{};
struct D//空结构体多大? C++ 1字节 ,C语言非法
{};
int main()
{
cout << "占有字节大小为:"<<sizeof(struct D) << endl;
cout << "占有字节大小为:" << sizeof(class C) << endl;
}
比对空类与空结构体:
- 空类和空结构体均占有一个字节大小
- C语言不允许存在空结构体
- C++结构体兼容C,可以存在空结构体
- 结构体默认为公有权限
- 类没有设置访问权限时,默认为私有权限
3、特殊类(虚函数)
在类中若出现虚函数时,需添加一个指针的数据大小
- 在X86(32位平台):一个指针的大小为 4字节
- 在X64 (64位平台):一个指针大小位 8字节
虚函数解析:
虚函数牵扯与派生类的函数覆盖问题,结合继承达成动态多态功能
由动态多态的本质可知,程序在编译过程无法得知函数调用的具体对象,只有运行过程中通过 调用对象保存的 虚函数指针(vptr:virtual pointer)指向的 虚函数表 的地址(vtbl:virtual table),得到调用的对象成员函数的具体地址得以实现。
class A //笔试经常考
{
public:
virtual void show()const//虚函数
{
cout << "m_a:" << m_a << ",m_b:" << m_b << endl;
}
virtual void seta(int a)
{
m_a = a;
}
virtual void setb(int b)
{
m_b = b;
}
private:
int m_a;
int m_b;
};
int main()
{
A a;
cout << "a的大小:" << sizeof(a) << endl;
return 0;
}
16 = 字节由两个整型成员对象(2*4字节)+ 一个64位平台下的指针(8字节)
总结:
虚函数的使用虽然具备动态多态,但在内存和执行速度有一部分成本:
- 每个对象都需要额外增加一个指针的大小
- 每次执行虚函数,都需要指针先跳转虚函数表查询函数地址,再跳转函数执行;相比普通函数多一步插叙虚函数表的操作
- 每个类需要创建一个虚函数表,保存虚函数地址