C++类的大小介绍

 更新时间:2021年11月12日 10:07:23   作者:学渣的C/C++  
这篇文章主要介绍了C++类的大小,在C++中,结构体和类的唯一区别就是结构体和类具有不同的默认访问控制属性,下面一起进入文章查看详细内容

1、C++结构体和类的关系

为什么讲C++类的大小要提到结构体呢,因为可能很多和我一样的学子,接触过C语言的结构体对齐,但不明白类的大小怎么计算,这其中都要用到内存对齐的概念,对于内存对齐的概念之前已经说过了,可以参考这篇博客:C++结构体字节对齐和共用体大小  明白结构体的内存大小计算后,就要明白类和结构体的关系:

在C++中,结构体和类的唯一区别就是:  结构体和类具有不同的默认访问控制属性。

  类中,对于未指定访问控制属性的成员,其访问控制属性为私有类型(private)。

  结构体中,对于未指定任何访问控制属性的成员,其访问控制属性为公有类型(public)。

所以结构体的大小和类的大小是一样的,在C++中,结构体也可以实现实现继承和多态(可能很惊讶,可以去看看这篇博文:C++结构体与类的区别详情,还要明确,静态成员变量和成员函数所占用的空间肯定不是结构体或类的空间。还有就是空的类的大小是1字节,以方便类进行实例化。

代码进行验证:

#include <iostream>
using namespace std;

struct Node {

};

class Test{

};

int main () {
    cout << "sizeof(struct Node) = " << sizeof(Node) << endl; 
    cout << "sizeof(class Test) =" << sizeof(Test) << endl;
    system("pause");
    return 0;

}

代码运行结果为:

 2、继承类的大小

继承允许我们依据另一个类来定义一个类,会把一个类的成员大小都继承下来,所以继承了的派生类大小一定要考虑基类的大小,首先考虑的最大对齐数,派生类的最大对齐数要考虑基类的最大对齐数。

下面以实际代码进行说明:

#include <iostream>
using namespace std;


class Base{
public:
    void func() {  //成员函数不占用类的空间大小

    }
private:
    static int m_val1; // 静态成员不占用类的空间
    int m_valInt;
    char m_valChar;
    double m_valDouble;
};

class Son:public Base{
public:
    static int func() { //静态成员函数也不占用内存空间
        return 0;
    }
private:
    int m_sonValint;
};


int main () {
    cout << "sizeof(Base) = " << sizeof(Base) << endl; 
    cout << "sizeof(Son)  = " << sizeof(Son) << endl;
    system("pause");
    return 0;

}

代码运行结果为:

 可以明确,静态成员变量和成员函数所占用的空间类的空间,所以Base类的最大对齐数为double类型的大小(8字节),按照顺序存储,

Base类的大小计算应该为:

sizeof(Base)= 4 + 1 + 3(浪费) + 8 = 16字节

Son类继承了Base类,它的最大对齐数也就是8字节,

所以Son类的大小计算应该为:

sizeof(Son)  = 4 + 1 + 3(浪费) + 8 + 8 = 24字节

注意类的也要考虑存储顺序,如果把Base类中的m_valChar放到m_valDouble后面,

Base类的大小计算就变成了:

sizeof(Base)= 4 + 4(浪费)+ 8 + 1 + 7(浪费)= 24字节

Son类的大小就算就变成了:

sizeof(Son)= 4 + 4(浪费)+ 8 + 1 + 3(浪费) +  4= 24字节

由此可以推算出多继承类的大小计算,菱形继承也是一样,都会继承基类的内存,尤其注意虚继承的情况,虚继承只是避免了菱形继承出现的二义性,但不是不继承,

如以下代码:

#include <iostream>
using namespace std;

class Base{
public:
    void func() {  //成员函数不占用类的空间大小

    }
public:
    double m_valDouble;
};

class Son1:virtual public Base{}; //虚继承
class Son2:virtual public Base{}; //虚继承
class GrandSon:public Son1,public Son2{};

int main () {
   
    cout << "sizeof(GrandSon)  = " << sizeof(GrandSon) << endl;
    GrandSon gs;
    // gs.m_valDouble = 10; //如果不是虚继承就会出现二义性
    
    system("pause");
    return 0;

}

代码运行结果为:

 上述GrandSon的依旧为16字节,因为它从Son1继承来了一份,又从Son2继承来了一份,所以,虚继承只是避免了访问的二义性,也可见菱形继承会对内存空间造成浪费 。

3、多态类的大小

多态类唯一的区别就是计算类大小要考虑到虚寒表指针的大小,指针的大小和系统相关,32位机器为4字节,64位机器为8字节,指针的大小也要作为最大对齐数的考虑范围。

代码说明如下:

#include <iostream>
using namespace std;

class Base{
public:
    virtual void func() = 0; //纯虚函数,会生成虚函数表指针
public:
    char m_valChar;
};

class Son: public Base{
public:
    void func() {};
public:
    int m_SonvalInt;
};

int main () {
   
    cout << "sizeof(Base) = " << sizeof(Base) << endl;
    cout << "sizeof(Son)  = " << sizeof(Son) << endl; 

    system("pause");
    return 0;

}

代码运行结果为:

 Base类的大小为8字节,是因为虚函数表指针占用了4字节,所以Base类的最大对齐数为4字节,虚函数表在构造函数的时候就会生成,所以,虚函数表指针肯定优先存储,

所以Base类大小的计算为:

sizeof(Base) = 4 + 1 + 3(浪费) = 8字节

则Son类的大小计算为:

sizeof(Son)= 4 + 1 + 3(浪费) + 4 = 12字节

到此这篇关于C++类的大小介绍的文章就介绍到这了,更多相关C++类的大小内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中的函数返回值问题

    C++中的函数返回值问题

    这篇文章主要介绍了C++中的函数返回值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • LeetCode题解C++生成每种字符都是奇数个的字符串

    LeetCode题解C++生成每种字符都是奇数个的字符串

    这篇文章主要为大家介绍了LeetCode题解C++生成每种字符都是奇数个的字符串示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • C++ Boost TypeTraits库使用详解

    C++ Boost TypeTraits库使用详解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C++缺省参数与重载函数(超详细!)

    C++缺省参数与重载函数(超详细!)

    无论使用什么语言函数都是代码段中必不可少的部分,因此我们有必要深入认识一下C++中函数的两种特殊用法,缺省参数,函数重载,这篇文章主要给大家介绍了关于C++缺省参数与重载函数的相关资料,需要的朋友可以参考下
    2024-06-06
  • C++ 使用VS Code运行程序时终端输出中文乱码的解决办法

    C++ 使用VS Code运行程序时终端输出中文乱码的解决办法

    这篇文章主要介绍了C++ 使用VS Code运行程序时终端输出中文乱码的解决办法 ,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • 15种 C++ 常见报错原因分析

    15种 C++ 常见报错原因分析

    这篇文章主要介绍了15种 C++ 常见报错,本文通过实例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • 用C语言实现圣诞树(简易版+进阶版)

    用C语言实现圣诞树(简易版+进阶版)

    大家好,本篇文章主要讲的是用C语言实现圣诞树(简易版+进阶版),感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • C++中将Char转换成String的4种方法

    C++中将Char转换成String的4种方法

    本文主要介绍了C++中将Char转换成String的4种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • c++插入排序详解

    c++插入排序详解

    插入排序的基本思想是每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。下面我们来详细探讨下C++实现插入排序
    2017-05-05
  • 浅析char 指针变量char *=p 这个语句的输出问题

    浅析char 指针变量char *=p 这个语句的输出问题

    下面小编就为大家带来一篇浅析char 指针变量char *=p 这个语句的输出问题。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05

最新评论