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的使用总结

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

C++ sizeof的使用总结

说明:以下代码在VS2008中通过,在32位操作系统下。 1.      定义 sizeof是一个操作符(operator)。 其作用是返回一个对象或类型所占的内存字节数。 其返回值类型为s...

c/c++ sizeof总结

偏移量:指的是结构体变量中成员的地址和结构体变量地址的差。 结构体大小等于最后一个成员的偏移量加上最后一个成员的大小. 0被认为是任何数的整数倍 求结构体大小的2个原则: 1.偏移量为该成员大...

C/C++中sizeof关键字总结

本文主要对C/C++中的sizeof关键字进行总结1. 基本数据类型 cout

C++面试中常被问的sizeof问题总结

本文参考http://www.cppblog.com/w57w57w57/archive/2011/08/09/152845.html又根据自己常被问及的问题和常犯的一些错误对其进行了一些补充。 ...

C++ sizeof 运算符总结

原博客:http://www.cppblog.com/w57w57w57/archive/2011/08/09/152845.html 自己理解后摘录、修改。 摘要: Sizeof的作用非常简单...
  • yes1cpp
  • yes1cpp
  • 2014年02月15日 21:10
  • 611

C、C++字符数组,字符指针,sizeof,strlen总结

对于字符数组与字符指针: 1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc",那么编译器帮你存储的是"abc\0". 2. 字符串直接量作为字符...
  • e_wsq
  • e_wsq
  • 2013年10月22日 19:35
  • 524

C++ sizeof用法总结

 sizeof   sizeof操作符的作用是返回一个对象或类型名的长度,长度的单位是字节。 返回值的类型是标准库命名为size_t的类型,size_t类型定义在cstddef头文件中,该...

C++笔试总结-面试笔试常考题型(一)指针-引用-宏定义-sizeof

面试总结的一些常考题型,包括sizeof,define,指针,引用等

C/C++ sizeof 总结

1、什么是sizeof    首先看一下sizeof在msdn上的定义:    The sizeof keyword gives the amount of storage, in byt...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++中关于sizeof使用的总结
举报原因:
原因补充:

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