Modern C++ sizeof(std::tuple)的秘密及实现代码解读

1. 前言

我们曾经至少三篇帖子或多或少的提到过std::tuple的原理及占用空间大小:

  1. Modern C++ std::tuple的size
  2. Modern C++利用工具快速理解std::tuple的实现原理
  3. GDB调试技巧实战–自动化画出类关系图
  4. Modern C++ std::unique_ptr的实现原理

但是,当初在第一篇中提出的size的问题还悬而未决,今天我将着重讲这一块,同时也会讲一些tuple的实现代码。

2. 类继承 VS 类has-a

2.1 一般继承与有一个父对象

考虑下面的两片代码:

struct Base {
   
   
	int i;
}; 
 
struct Derived1 : Base
{
   
   
    int j;
};
struct Base {
   
   
	int i;
}; 
 
struct Derived1
{
   
   
	Base b;
    int j;
};

本质上没有什么区别,第一种是继承Base, 也相当于has a Base。它们的sizeof大小也相同。
加强训练下,猜下下面的程序的输出???:

#include<iostream>
#include <tuple>
using namespace std;


struct Base {
   
   
	int i;
}; // empty class

struct Derived1 : Base
{
   
   
    int i;
};

struct Derived2 : Base
{
   
   
    int i;
};

struct Derived3 : Derived2, Derived1
{
   
   
};

int main()
{
   
   
	Derived3 d;
	std::cout<<sizeof(d)<<std::endl;
}

我没有给初始化,所以i的值比较随机,这反而能看出我们真的有4个i, 特别是Base.i有两个:

(gdb) p d
$1 = {
   
   <Derived2> = {
   
   <Base> = {
   
   i = -10544}, i = 32767}, <Derived1> = {
   
   <Base> = {
   
   i = 0}, i = 0}, <No data fields>}

2.2 继承空类 VS 有一个空类对象

但是,如果把Base换成空类哪?如果没有优化,第一种情况还相当于has a Base其大小是1,加上一个int总共8字节(有对其)。但历史没有假设,标准还偏偏允许有优化:Empty base optimization
继承的情况大小为4字节,比has a情况少用4个字节!

2.3 std::tuple中放空类对象 – 继承空类

一言以蔽之:std::tuple正是用了继承而非has a 而节约的空间。
我们举个例子,就举《Modern C++ std::unique_ptr的实现原理》中的例子吧,std::unique_ptr的本质是std::tuple<int*, std::default_delete>, 它的大小是指针的大小8,而不是16. 写个程序验证一下:

#include<iostream>
#include <tuple>
#include <memory>
using namespace std;

int main()
{
   
   
	int i=5;
	std::tuple<int*

相关推荐

  1. Modern C++ sizeof(std::tuple)秘密实现代码解读

    2024-01-31 08:54:01       67 阅读
  2. ChatGPT:实现高效论文写作秘密武器

    2024-01-31 08:54:01       43 阅读
  3. 探索股票量化统计:解析市场数据秘密

    2024-01-31 08:54:01       29 阅读
  4. 深度解析:scikit-learn Pipeline记忆功能秘密

    2024-01-31 08:54:01       26 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-31 08:54:01       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-31 08:54:01       97 阅读
  3. 在Django里面运行非项目文件

    2024-01-31 08:54:01       78 阅读
  4. Python语言-面向对象

    2024-01-31 08:54:01       88 阅读

热门阅读

  1. Mongodb投射中的$slice,正向反向跳过要搞清楚

    2024-01-31 08:54:01       50 阅读
  2. waymo open dataset v2.0.0 (Perception dataset) 大小

    2024-01-31 08:54:01       50 阅读
  3. Flask和Go框架相比

    2024-01-31 08:54:01       55 阅读
  4. K8S故障临时设置节点为不可调度

    2024-01-31 08:54:01       48 阅读
  5. uniapp的安卓升级功能说明

    2024-01-31 08:54:01       58 阅读
  6. 动态规划入门题目

    2024-01-31 08:54:01       61 阅读
  7. CUDA 笔记

    2024-01-31 08:54:01       53 阅读