Skip to content

Files

Latest commit

3c8a3f2 · Mar 30, 2024

History

History

sizeof

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Mar 30, 2024
Feb 1, 2023
Mar 30, 2024
Mar 30, 2024
Mar 30, 2024
Mar 30, 2024
Mar 30, 2024
Mar 30, 2024
Mar 30, 2024
Mar 30, 2024

类大小计算

首先来个总结,然后下面给出实际例子,实战!

  • 空类的大小为1字节
  • 一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间。
  • 对于包含虚函数的类,不管有多少个虚函数,只有一个虚指针,vptr的大小。
  • 普通继承,派生类继承了所有基类的函数与成员,要按照字节对齐来计算大小
  • 虚函数继承,不管是单继承还是多继承,都是继承了基类的vptr。(32位操作系统4字节,64位操作系统 8字节)!
  • 虚继承,继承基类的vptr。

1.原则1

/**
 * @file blackclass.cpp
 * @brief 空类的大小为1字节
 * @author 光城
 * @version v1
 * @date 2019-07-21
 */
#include<iostream>
using namespace std;
class A{};
int main()
{
    cout<<sizeof(A)<<endl;
    return 0;
}

2.原则2

/**
 * @file static.cpp
 * @brief 静态数据成员
 * 静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员,但不影响类的大小。不管这个类产生了多少个实例,还是派生了多少新的类,静态数据成员只有一个实例。静态数据成员,一旦被声明,就已经存在。 
 * @author 光城
 * @version v1
 * @date 2019-07-21
 */
#include<iostream>
using namespace std;
class A
{
    public:
        char b;
        virtual void fun() {};
        static int c;
        static int d;
        static int f;
};

int main()
{
    /**
     * @brief 16  字节对齐、静态变量不影响类的大小、vptr指针=8
     */
    cout<<sizeof(A)<<endl; 
    return 0;
}

3.原则3

/**
 * @file morevir.cpp
 * @brief 对于包含虚函数的类,不管有多少个虚函数,只有一个虚指针,vptr的大小。
 * @author 光城
 * @version v1
 * @date 2019-07-21
 */
#include<iostream>
using namespace std;
class A{
    virtual void fun();
    virtual void fun1();
    virtual void fun2();
    virtual void fun3();
};
int main()
{
    cout<<sizeof(A)<<endl; // 8
    return 0;
}

4.原则4与5

/**
 * @file geninhe.cpp
 * @brief 1.普通单继承,继承就是基类+派生类自身的大小(注意字节对齐)
 * 注意:类的数据成员按其声明顺序加入内存,无访问权限无关,只看声明顺序。
 * 2.虚单继承,派生类继承基类vptr
 * @author 光城
 * @version v1
 * @date 2019-07-21
 */

#include<iostream>

using namespace std;

class A
{
    public:
        char a;
        int b;
};

/**
 * @brief 此时B按照顺序:
 * char a
 * int b
 * short a
 * long b
 * 根据字节对齐4+4+8+8=24
 * 
 * 或编译器优化
 * char a
 * short a
 * int b
 * long b
 * 根据字节对齐2+2+4+8=16
 */
class B:A
{
    public:
        short a;
        long b;
};
/**
* 把A的成员拆开看,char为1,int为4,所以是1+(3)+4+1+(3)=12,()为字节补齐
*/
class C
{
    A a;
    char c;
};

class A1
{
    virtual void fun(){}
};
class C1:public A1
{
};


int main()
{
    cout<<sizeof(A)<<endl; // 8
    cout<<sizeof(B)<<endl; // 16 或 24
    cout<<sizeof(C)<<endl; // 12

    /**
     * @brief 对于虚单函数继承,派生类也继承了基类的vptr,所以是8字节
     */
    cout<<sizeof(C1)<<endl; // 8 
    return 0;
}

5.原则6

/**
 * @file virnhe.cpp
 * @brief 虚继承
 * @author 光城
 * @version v1
 * @date 2019-07-21
 */

#include<iostream>
using namespace std;
class A
{
    virtual void fun() {}
};
class B
{
    virtual void fun2() {}
};
class C : virtual public  A, virtual public B
{
    public:
        virtual void fun3() {}
};

int main()
{
    /**
     * @brief 8 8 16  派生类虚继承多个虚函数,会继承所有虚函数的vptr
     */
    cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C);

    return 0;
}