C++中关于sizeof使用的总结

原创 2016年08月30日 16:10:53

一、内存字节对齐

参考

    写出一个class,然后sizeof,sizeof的结果往往都比你声明的变量总长度要大,这是因为字节对齐。显然对齐更浪费了空间。那么为什么要使用对齐呢?对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。

1. 数据成员对齐规则:类中的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(比如说是数组)的整数倍开始
2. 类作为成员:如果一个类中里有其他类成员,则其他类成员要从其内部最大元素大小的整数倍地址开始存储.(class A里存有class B,B里有char,int ,double等元素,那B应该从8的整数倍开始存储.)
3. 收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

    class A  
    {  
        int i;//0.3  
        short s[5];//4.14  
        char c;//15.16 规则3  
    };  
    class B  
    {  
        char c0;//0.7  
        double d[3];//8.32  规则1
        char c;//33.40 规则3 
    };  

二、一个空类的sizeof的大小

class Test{

};

sizeof(Test)的结果是1.

 因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。

三、不含成员变量,仅含构造函数和析构函数类的大小

class Test2{
    Test2(){

    }
    ~Test2(){

    }
};

sizeof(Test2)的结果是1.

 因为普通成员函数与sizeof无关。 

四、不含成员变量,含虚析构函数

class Test3{
    //long long i;
    Test3(){

    }
    virtual ~Test3(){

    }
};

sizeof(Test3)的结果是4.

 因为虚函数放在虚表中,类中定义了虚函数,需要存放一个指向虚表的指针。指针占4个字节 

五、测试

测试

#include<iostream>
using namespace std;
class A
{
public:
     int a;
private:
    char b;
};
class B
{
public:
    static int a;
private:
    char b;
};
class C
{
public:
    int a;
    virtual void f(){}
};
class D
{
public:
    int a;
    virtual void f(){}
    virtual void f2(){}
    virtual void f3(){}
};
//普通继承
class E
{
public:
    int a;
private:
    char b;
};
class F : public E
{
public:
    int d;
    char c;

};
class G
{
public:
    int a;
private:
    char b;
};
class H : public G
{
public:
    char c;
    int d;
};
//普通继承含虚函数的父类
class Test
{
public:
    char a;
    virtual void get(){}
};
class Test2 : public Test
{
public:
    int a;
};
//含虚函数的子类普通继承含虚函数的父类
class Test3
{
public:
    int a;
    virtual void get(){}
};
class Test4: public Test3
{
public:
    int a;
    virtual void set(){}
};
//子类虚继承父类
class Test5
{
public:
    int a;
};
class Test6 : virtual public Test5
{
public:
    int b;
};
//子类和父类中都含虚函数的虚继承
//使用虚继承,子类和父类的虚函数存放在不同的虚表中,因此子类和父类都需要一个指向虚表的指针。
class Test7
{
public:
    int a;
    virtual void get(){}
};
class Test8 : virtual Test7
{
public:
    int a;
    virtual void set(){}
};
//多重继承
class Test9
{
public:
    int a;
};
class Test10 : public Test9
{
public:
    int b;
};
class Test11 : public Test9
{
public:
    int c;
};
class Test12 : public Test10, public Test11
{
public:
    int d;
};
//多重虚继承,由于是虚继承,虚基类数据成员a只需要保留一份。
class Test13
{
public:
    int a;
};
class Test14 : virtual public Test13
{
public:
    int b;
};
class Test15 : virtual public Test13
{
public:
    int c;
};
class Test16 : public Test14, public Test15
{
public:
    int d;
};

int   main()
{
    cout << sizeof(A) << endl;//8
    cout << sizeof(B) << endl;//1
    cout << sizeof(C) << endl;//8
    cout << sizeof(D) << endl;//8
    cout << sizeof(E) << endl;//8
    cout << sizeof(F) << endl;//16
    cout << sizeof(G) << endl;//8
    cout << sizeof(H) << endl;//16
    cout << sizeof(Test) << endl;//8
    cout << sizeof(Test2) << endl;//12
    cout << sizeof(Test3) << endl;//8
    cout << sizeof(Test4) << endl;//12
    cout << sizeof(Test5) << endl;//4
    cout << sizeof(Test6) << endl;//12
    cout << sizeof(Test7) << endl;//8
    cout << sizeof(Test8) << endl;//20
    cout << sizeof(Test9) << endl;//4
    cout << sizeof(Test10) << endl;//8
    cout << sizeof(Test11) << endl;//8
    cout << sizeof(Test12) << endl;//20
    cout << sizeof(Test13) << endl;//4
    cout << sizeof(Test14) << endl;//12
    cout << sizeof(Test15) << endl;//12
    cout << sizeof(Test16) << endl;//24

    system("PAUSE");
}

六、普通继承总结

  1. 类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
  2. 普通成员函数与sizeof无关。
  3. 虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节。
  4. 类的总大小也遵守类似class字节对齐的,调整规则。

七、虚继承

class   Parent
{
protected:
    int   x;
public:
    Parent(){ }
    virtual   ~Parent(){}

};
class   Child:virtual   public   Parent
{
protected:
    int   y;
public:
    Child() :Top(){}
};

sizeof(Parent)的结果为8,sizeof(Child)的结果为16

因为虚继承,虚继承的子类都要包含一个指向基类的指针

C++类的大小——sizeof(class)

第一:孔磊d class CBase { }; 运行cout sizeof(CBase)=1; 为什么空的什么都没有是1呢?查资料……查啊查……OK这里了:先了解一个概念:类的实例化,所谓类的...
  • yangyangye
  • yangyangye
  • 2014年08月03日 22:06
  • 6087

常问面试题:C++中sizeof的陷阱及应答

http://blog.csdn.net/lanxuezaipiao/article/details/19013833 C++中sizeof是经常被问到的一个概念,比如,下面的几个关于s...
  • xtzmm1215
  • xtzmm1215
  • 2015年03月11日 19:24
  • 1192

C/C++介绍sizeof函数

0. 前向声明 sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着“辛苦我一个,幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。 但当我总结的时候才发...
  • lj695242104
  • lj695242104
  • 2013年11月17日 19:55
  • 4009

浅析C++中sizeof操作符的用法

1. 概要 sizeof是C/C++中的一个操作符(operator),作用就是返回一个对象或者类型所占的内存字节数。返回值类型为size_t,在头文件stddef.h中定义.这是一个依赖于编译系统...
  • wangshubo1989
  • wangshubo1989
  • 2015年08月31日 11:27
  • 1947

C++类中包含stl容器时,使用sizeof求大小的问题

这里的大小指的是sizeof(a class object)的值,也就是一个类的对象所占的字节大小,原来我一直认为类的大小会随着类成员中容器元素个数的变化而变化,后来想想又想不通,所以写了下面的代码用...
  • shihengzhen101
  • shihengzhen101
  • 2015年11月18日 22:45
  • 1338

C++ sizeof各种类型的大小

C++各种类型的sizeof大小,指针、参数、类、内存对齐、虚函数等。
  • ynnmnm
  • ynnmnm
  • 2015年05月18日 20:42
  • 3012

C++ sizeof的使用总结

说明:以下代码在VS2008中通过,在32位操作系统下。 1.      定义 sizeof是一个操作符(operator)。 其作用是返回一个对象或类型所占的内存字节数。 其返回值类型为size_t...
  • hanshuilingyue
  • hanshuilingyue
  • 2013年11月27日 10:37
  • 297

C++ sizeof的使用总结

说明:以下代码在VS2008中通过,在32位操作系统下。 1.      定义 sizeof是一个操作符(operator)。 其作用是返回一个对象或类型所占的内存字节数。 其返回值类型为si...
  • jueqian
  • jueqian
  • 2015年07月18日 09:55
  • 232

C++ sizeof的使用总结

转自:http://blog.csdn.net/candyliuxj/article/details/6307814 说明:以下代码在VS2008中通过,在32位操作系统下。 1.    ...
  • MegatronC
  • MegatronC
  • 2013年05月13日 00:03
  • 292

C++ sizeof的使用总结

1.     定义 sizeof是一个操作符(operator)。 其作用是返回一个对象或类型所占的内存字节数。 其返回值类型为size_t。(size_t在头文件stddef.h中定义,它依赖...
  • chenhongming888
  • chenhongming888
  • 2017年04月16日 11:51
  • 51
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++中关于sizeof使用的总结
举报原因:
原因补充:

(最多只允许输入30个字)