首页 > 其他分享 >C-中类所占的空间

C-中类所占的空间

时间:2023-07-01 19:55:42浏览次数:38  
标签:字节 对象 占用 cout print 空间 中类 struct

类所占的空间

概览

struct A
{
   public:
};

std::cout<<"sizeof(A):"<<sizeof(A)<<std::endl; // sizeof(A):1

A是一个空类,如果直接输出A所占的字节会发现只有1个字节。可见对象至少占一个字节。

struct B
{
   public:
   void func(){};
   void func1(){};
};

struct C{
   //char variable;
   int x;
};

std::cout<<"sizeof(B):"<<sizeof(B)<<std::endl; //  sizeof(B):1
std::cout<<"sizeof(C):"<<sizeof(C)<<std::endl; //  sizeof(C):4

B只含有两个成员函数,依然只占1个字节。成员函数不占用类对象本身的内存空间。而C会占用4个字节。可见:每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间

对象结构小总结

1、 非静态的成员变量跟着类对象走(存在对象内部),换言之,每个类对象都有自己的成员变量。

2、 静态成员变量不会保存在对象内部。

struct D
{
   static int x;
   static int y;
};
std::cout<<"sizeof(D)"<<std::endl; // sizeof(D):1

类D所占字节也依旧是1个字节。

3、无论是静态还是非静态成员函数,都保存在对象之外, 不占用类对象的内存空间。

4、如果类内部有虚函数(无论有多少个虚函数所占空间一致),其会占用对象内部一部分内存空间。具体占用大小由是64位机还是32位机来定义。本人在Fedora36上测试,如果类里含有虚函数,对象会额外多出8个字节。

struct E
{
   virtual void func(){};
   virtual void func1(){};
};
std::cout<<"sizeof(E):"<<sizeof(E)<<std::endl; // sizeof(E):8

之所以会多出8个字节,是因为对象内部会多出一个指向虚函数表的指针(在64位机上,void*指针会占用8个字节)。

5、 如果有多个数据成员,

struct F
{
   int x;
   char y;
};
std::cout<<"sizeof(F):"<<sizeof(F)<<std::endl; // sizeof(F):8

虽然数据成员x和y加起来总共有5个字节,但是为了进行内存对齐,实际F的对象占用8个字节。

this指针调整

我们考虑以下多重继承的情况:

struct A
{
    int x;
    A():x(0)
    {
        std::cout<<"A() this:"<<this<<std::endl;
    }
    A(int x):x(x)
    {
        std::cout<<"A() this:"<<this<<std::endl;
    }
    void print_athis()
    {
        std::cout<<"print_athis() ";
        std::cout<<"this:"<<this<<std::endl;
    }
};

struct B
{
    int x;
    B() :x(0)
    {
        std::cout<<"B() this:"<<this<<std::endl;
    }
    B(int x):x(x)
    {
        std::cout<<"B() this:"<<this<<std::endl;
    }
    void print_bthis()
    {
        std::cout<<"print_bthis() ";
        std::cout<<"this:"<<this<<std::endl;
    }
};

struct C: public A, public B
{
    int x;
    C():x(0)
    {
        std::cout<<"C() this:"<<this<<std::endl;
    }
    C(int x):x(x)
    {
        std::cout<<"C() this:"<<this<<std::endl;
    }
    void print_cthis()
    {
        std::cout<<"print_cthis() ";
        std::cout<<"this:"<<this<<std::endl;
    }
};

接着我们分别调用各自的成员函数,看看各自的this指针地址。

C myc{};
myc.print_athis();
myc.print_bthis();
myc.print_cthis();

输出:

A() this:0x7ffc2d763a44
B() this:0x7ffc2d763a48
C() this:0x7ffc2d763a44
print_athis() this:0x7ffc2d763a44
print_bthis() this:0x7ffc2d763a48
print_cthis() this:0x7ffc2d763a44

我们会发现,类A会与类C共享同一个地址。
这里,我们可以得到结论:派生类是包含基类子对象的。且二者指向的地址相同。如果出现多重继承的情况,那么只有第一个基类子对象与派生类地址相同。后续的基类子对象会根据前面继承的基类子对象的大小决定其地址。

如果我们在类C中也覆盖print_bthis()函数,那么就会输出print_bthis() this:0x7ffc2d763a44

标签:字节,对象,占用,cout,print,空间,中类,struct
From: https://www.cnblogs.com/wyfc4/p/17519817.html

相关文章

  • Linux索引节点(Inode)用满导致空间不足
    1、问题:在创建新目录和文件是提示“nospaceleftondevice”!按照以前的情况,很有可能是服务器空间又被塞满了,通过命令查看,发现还有剩余。再用df-i查看了一下/分区的索引节点(inode),发现已经用满(已用=100%),导致系统无法创建新目录和文件。2、问题原因分析:Inode译成中文就是索引节......
  • 蓝图-位置空间变换
    节点含义NewLocation设置新的坐标位置,右键选择SplitStructPin可将xyz坐标进行拆分Sweep不选中时,如果初位置和末尾置中间有物体将无视而直接到达目标位置选中时,初末位置中间有物体将因为碰撞结果而不能到达目标位置Teleport勾选,继承物理属性SweepHitResul......
  • MySQLINNODB表空间分类简单介绍
     MySQLINNODB表空间分类简单介绍 从功能上看INNODB表空间共以下几种:系统表空间File-Per-Table表空间通用表空间Undo表空间临时表空间 从共享与否角度看上边提到的五种表空间可以这么归类。共享表空间独立表空间官档中有明确提到“共享表空间”这个说法:http......
  • 【改进蚁群算法】 蚁群算法 Dijkstra算法 遗传算法 人工势场法实现二维 三维空间路径
    【改进蚁群算法】蚁群算法Dijkstra算法遗传算法人工势场法实现二维三维空间路径规划本程序为改进蚁群算法+Dijkstra算法+MAKLINK图理论实现的二维空间路径规划 算法实现:原创文章,转载请说明出处,资料来源:http://imgcs.cn/5c/636749258569.html1)基于MAKLINK图理论生成地图,并对......
  • Winform DataGridView空间绘制单元格内容
    在项目中遇到一个需求,需将特定单元格内data显示为修饰后的内容,但不改变原始值(例如将data内的时间单位为ms,单元格需显示ms或者根据值显示特定名称)CellValueNeeded,该事件在控件刷新,需要为单元格填充数据时发生,其参数e返回当前单元格的行和列,根据行和列,获取需要的值,赋给e的Value属性......
  • 定义命名空间
     命名空间的定义使用关键字 namespace,后跟命名空间的名称,如下所示:namespacenamespace_name{//代码声明}为了调用带有命名空间的函数或变量,需要在前面加上命名空间的名称,如下所示:name::code;//code可以是变量或函数https://www.lekaowang.com/jkgls/fdsg/......
  • C++ 命名空间
     假设这样一种情况,当一个班上有两个名叫Zara的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。同样的情况也出现在C++应用程序中。例如,您可能会写一个名为xyz()的函数,在另一个可用的库中也存在一个相同的......
  • SAP UI5 命名空间 com.sap.vocabularies.Common.v1 的作用
    SAPUI5是一种基于JavaScript的用户界面技术,用于构建企业级Web应用程序。它提供了一套丰富的控件库,可以帮助开发者轻松地创建响应式、跨平台的用户界面。命名空间是一种在编程中常见的概念,用于区分不同的代码库或功能模块,以避免命名冲突。com.sap.vocabularies.Common.v1是......
  • SAP UI5 sap.ui.layout 命名空间的作用介绍
    SAPUI5是一种用于构建企业级Web应用程序的开发框架。它提供了丰富的UI控件和工具,使开发人员能够快速构建现代化、可扩展和可定制的应用程序。在SAPUI5中,sap.ui.layout是一个重要的命名空间,用于提供布局和容器相关的控件和功能。下面将详细介绍sap.ui.layout的作用和一些示例。......
  • rancher删除命名空间
    #指定需要删除的命名空间NAMESPACE='monitoring'#以下为固定格式,不需要修改RANCHER_SERVER_URL=$(kubectlconfigview-ojson|jq-r.clusters[0].cluster.server)CLUSTER_TOKEN=$(kubectlconfigview-ojson|jq-r.users[0].user.token)#获取删除finalizers后的命......