背景
C++ 中每个对象的实例都可以通过取地址运算符获取其在内存布局中的开始位置,因此每个类对象至少需要占用一个字节的空间。
空类的大小
①.概述
空类是指不包含非静态数据成员的类,但是可以包含成员函数及静态成员。C++ 中空类的大小是 1 字节。
②.空类的大小
class emptyClassA
{
};
class emptyClassB
{
static int i;
};
class emptyClassC
{
public:
void func1() {};
void func2() {};
};
int main()
{
cout << "emptyClassA 大小:" << sizeof(emptyClassA) << endl;
cout << "emptyClassB 大小:" << sizeof(emptyClassB) << endl;
cout << "emptyClassC 大小:" << sizeof(emptyClassC) << endl;
return 0;
}
空基类优化
①.概述
在没有歧义的情况下,C++ 允许空基类的子对象大小为 0。
②.应用空基类优化
struct Base{ };
struct Derived1 :Base{
int i;
};
③.不应用空基类优化
struct Derived2 :Base {
Base b;
int i;
};
空基类优化的应用
①.概述
一般来讲,对一个既有类进行扩展时,除非有更好的理由采用继承(有虚函数需要重新实现、有受保护的私有成员需要访问,否则采用组合的方式进行扩展。
②.空基类优化的应用场景
空类只是没有数据成员,依然可以包含成员函数,即一个空类同样是可以提供某种功能。当一个类要通过一个空类来扩展功能时,采用继承比组合的方式更节省内存空间,且使用方式是一样的。
class Base {
public:
void func() { cout << "base::func()" << endl; }
};
class Derived1 :public Base {
int i;
};
class Derived2
{
Base b;
int i;
public:
void func() { b.func(); }
};
int main()
{
Derived1 d1;
Derived2 d2;
d2.func();
d1.func();
cout << "Derived1 大小:" << sizeof(Derived1) << endl;
cout << "Derived2 大小:" << sizeof(Derived2) << endl;
return 0;
}
③.基于策略的设计
在惯用法基于策略的设计即是应用了空基类优化,通过继承来扩展类的功能。
template<typename T>
class demoClass:public T
{
};
class func_policy1
{
public:
void func() { cout << "used func1" << endl; }
};
class func_policy2
{
public:
void func() { cout << "used func2" << endl; }
};
int main()
{
demoClass<func_policy1> demo;
demo.func();
system("pause");
return 0;
}