C++ 空基类优化
1. 继承体系中的内存模型
我们都知道,在C++中,不存在大小是零的类。即便是空类,也要占据一个字节,否则无法比较两个空类对象是否是同一个对象(在C/C++中,默认使用地址来判断两个变量是否是同一个)。
class BaseEmpty {
public:
BaseEmpty() { std::cout<<"Base address: "<< this << std::endl;}
};
int main(int argc, char const *argv[]) {
BaseEmpty empty_1{};
BaseEmpty empty_2{};
assert(&empty_1 != &empty_2); // 两个空类对象的地址肯定不同
std::cout<<sizeof(BaseEmpty{})<<std::endl; // 输出 1
}
Dervied_1
继承了父类Base
,Derived_1
的内存模型等效于Derived_2
class Base {
public:
Base() = default;
private:
int num_{0};
bool state_{false};
};
class Derived_1 : public Base {
public:
Derived_1() = default;
private:
std::string name_{"CPP"};
};
class Derived_2 {
public:
Derived_2() = default;
private:
int num_{0};
bool state_{false};
// 子类的成员变量
std::string name_{"CPP"};
};
2. 空基类优化
对于空类BaseEmpty
,假设有另一个空类DerivedEmpty
继承自BaseEmpty
,空类DerivedDeeperEmpty
继承自DerivedEmpty
,那么DerivedDeeperEmpty
对象的大小sizeof(DerivedDeeperEmpty{})
会是几个字节???
class DerivedEmpty: public BaseEmpty {
public:
DerivedEmpty() {
std::cout<<"Derived address: "<< this << std::endl;
}
};
class DerivedDeeperEmpty: public DerivedEmpty {
public:
DerivedDeeperEmpty() {
std::cout<<"deeper address: "<< this << std::endl;
}
};
DerivedDeeperEmpty
是个空类,也要占用两个字节,相当于内部分别包含了BaseEmpty
、DerivedEmpty
class DerivedDeeperEmpty_eq {
public:
DerivedDeeperEmpty_eq() = default;
private:
BaseEmpty base_1_;
DerivedEmpty base_2_;
};
sizeof(DerivedDeeperEmpty_eq); // 2
DerivedDeeperEmpty
明明只是个空类啊!!!大小却是2个字节???如果情况再极端点,DerivedDeeperEmpty
还有更深的空子类,那么空子类的大小会不断膨胀???
在空类被用作基类时,如果不给它分配内存并不会导致它被存储到与同类型对象(包括子类对象)相同的地址上,那么就可以不给它分配内存。换句话说,BaseEmpty
作为空基类时,下面两种情况,编译器不会为Basement对象在子类中分配内存:
-
子类单继承,比如类DerivedDeeperEmpty。
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)