我是靠谱客的博主 谦让蚂蚁,最近开发中收集的这篇文章主要介绍cpp中使用sizeof和计算类占用空间的大小,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

cpp中使用sizeof和计算类占用空间的大小

cpp中的sizeof的特性

cpp中sizeof的特性

(0)sizeof是运算符,不是函数;
(1)sizeof不能求得void类型的长度;
(2)sizeof能求得void类型的指针的长度;
(3)sizeof能求得静态分配内存的数组的长度!
(4)sizeof不能求得动态分配的内存的大小!
(5)sizeof不能对不完整的数组求长度;
(6)当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值!
(7)sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不执行函数体!
(8)sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和!
(9)sizeof不能用于求结构体的位域成员的大小,但是可以求得包含位域成员的结构体的大小!

操作符和函数的区别

运算符是内置于语言的,函数是所带的库里面的。当然是前者的效率要高一些,不存在函数调用。

1 sizeof是运算符,不是函数;

定义 sizeof是C/C++中的一个操作符(operator)是也,简单的说其作用就是返回一个对象或者类型所占的内存字节数。

2 sizeof不能求得void类型的长度;

    //cout << sizeof(tfunc1()) << endl;//错误
    cout << sizeof(tfunc2()) << endl;

3 sizeof能求得void类型的指针的长度

    void *p;
    cout << sizeof(p) << endl;

4 sizeof能求得静态分配内存的数组的长度

    char arr1[30];
    cout << sizeof(arr1) << endl;

5 sizeof不能求得动态分配的内存的大小

    char *arr2 = new char[30];
    cout << sizeof(arr2) << endl;

6 sizeof不能对不完整的数组求长度,这里的不完整的数组是指数组大小没有确定的数组

    假设有两个源文件:file1.cpp和file2.cpp,其中file1.cpp定义:
    int arrayA[10]={1,2,3,4,5,6,7,8,9,10};
    int arrayB[10]={11,12,13,14,15,16,17,18,19,20};
    file2.cpp中包含如下几个语句:extern arrayA[]; extern arrayB[10];
    cout<<sizeof(arrayA)<<endl;   //编译出错
    cout<<sizeof(arrayB)<<endl;

7 当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值

    int a = 11;
    int a2 = sizeof(a+2);
    cout << a2<<endl;

8 sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不执行函数体

    int a3 = sizeof(tfunc2());
    cout << a3 << endl;

9 sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和!

typedef struct {
    char aChar;//1
    float aFloat;//4
    short aShort;//2
}st1;

cout << sizeof(st1) << endl;

10 sizeof不能用于求结构体的位域成员的大小,但是可以求得包含位域成员的结构体的大小!

 //cout << sizeof(st1.aFloat) << endl;//error

据说有一个不通过sizeof求int长度的题目可以利用地址间的减法求得

    int arr3[4];
    cout << (unsigned  long)&arr3[1] -(unsigned long) &arr3[0] << endl;

对类使用sizeof

1 类的sizeof大小一般是类中的所有成员的sizeof大小之和

    class TestA{
    public:
        TestA();
        ~TestA();
        void t1(){ cout << "abc";}
        int f2(){return 123;}
    };


    class TestB{
    public:
        TestB();
        ~TestB();
    private:
        int int1;
        int age;
    };

    //空类的大小为1
    cout << "sizeof TestA a=" << sizeof(TestA) << endl;
    //含有成员函数的类的大小8
    cout << "sizeof TestB =" << sizeof(TestB) << endl;

2 当类中含有虚成员函数的时候,在类中隐藏了一个指针,该指针指向虚函数表-一个虚表有8个指针

    class TestC{
    public:
        TestC();
        ~TestC();
        virtual int sss(){ return age;}
    private:
        int int1;
        int age;
    };

     //含有虚表 8+8=16
    cout << "sizeof TestC=" << sizeof(TestC) << endl;

        class TestC{
    public:
        TestC();
        ~TestC();
        virtual int sss(){ return age;}
         virtual int sss2(){ return age;}
          virtual int sss3(){ return age;}
    private:
        int int1;
        int age;
    };

     //含有虚表 8+8=16
    cout << "sizeof TestC=" << sizeof(TestC) << endl;

简单说下继承与虚基础的区别

虚继承不管父类派生出多少个子类在内存总只存在一套数据,但是一般继承会存在与派生类个数对应的N个数据

如果是虚函数的单继承呢?

    class TestD{
    public:
        virtual void sss(){}
    };

    class TestE:public TestD{
    public:
        virtual void sss2(){}

    };

    class TestF:virtual public TestD{
    public:
    virtual void sss3(){}
    };

    class TestE2:public TestE{
    public:
        virtual void sss2(){}

    };

    //输出8
    //简单继承  
    cout << "sizeof TestD=" <<  sizeof(TestD) << endl;

    //输出8
    //TestE 继承了TestD 的虚表,他自己的虚函数也放在同一张虚表里面
    cout << "sizeof TestE=" <<  sizeof(TestE) << endl;

     //虚继承,其实也是一样的 
    cout << "sizeof TestF=" <<  sizeof(TestF) << endl;

    因为他们都是把数据放到一张虚表,当时单继承的时候只会存在一张虚表,存放所有的虚函数

如果是虚函数的多继承呢?

    class TestD{
public:
    virtual void sss(){}
};

class TestE:public TestD{
public:
    virtual void sss2(){}

};

class TestF:virtual public TestD{
public:
    virtual void sss3(){}

};

class TestG:public TestD{
public:
    virtual void sss3(){}
};


class TestH:public TestE,public TestG{

};

//多继承呢 输出16
cout << "sizeof TestH=" <<  sizeof(TestH) << endl;


多继承的时候会存在多张虚表,和他继承的父亲的数量有关系

总结下sizeof的用法:

不涉及到类的请参考前面的10条规则

涉及到类的:

    1 类的sizeof大小一般是类中的所有成员的sizeof大小之和,普通函数不计入sizeof

    2 当类中含有虚成员函数的时候,在类中隐藏了一个指针,该指针指向虚函数表-一个虚表有8个指针  
    3 当类含有继承关系的时候,如果是单继承,只会有一张虚表,sizeof(类)的大小=成员大小+8
    4 当类含有继承关系的时候,如果是多继承,与父类的数量和父类含有的虚表的数量有关系
    sizeof(类)的大小=成员大小+8 *(含有虚表的父类的数量)

参考博客

http://www.cppblog.com/w57w57w57/archive/2011/08/09/152845.html
http://blog.sina.com.cn/s/blog_7c983ca60100yfdv.html

附上我的测试代码


//
//  main.cpp
//  use_sizeof
//
//  Created by bikang on 16/10/27.
//  Copyright (c) 2016年 bikang. All rights reserved.
//

#include <iostream>
using namespace std;


typedef struct {
    char aChar;//1
    float aFloat;//4
    short aShort;//2
}st1;

void tfunc1();
int tfunc2();

void tsizeofArr1(char arr[]);
//测试sizeof的特性
void tsizeof();

//对类使用sizeof
void tclassSizeof();

//只含有放的类
class TestA{
public:
    TestA();
    ~TestA();
    void t1(){ cout << "abc";}
    int f2(){return 123;}
};


class TestB{
public:
    TestB();
    ~TestB();
private:
    int int1;
    int age;
};

class TestC{
public:
    TestC();
    ~TestC();
    virtual int sss(){ return age;}
    virtual int sss2(){ return age;}
    virtual int sss3(){ return age;}
private:
    int int1;
    int age;
};


class TestD{
public:
    virtual void sss(){}
};

class TestE:public TestD{
public:
    virtual void sss2(){}

};

class TestE2:public TestE{
public:
    virtual void sss2(){}

};


class TestF:virtual public TestD{
public:
    virtual void sss3(){}

};

class TestG:public TestD{
public:
    virtual void sss3(){}
};

class TestG2:public TestD{
public:
    virtual void sss3(){}
};

class TestH:public TestE,public TestG{

};

class TestH2:public TestE,public TestG,public TestG2{

};

class TestG3{

};

class TestH3:public TestE,public TestG,public TestG2,public TestG3{

};

class TestI:virtual public TestE,virtual public TestG{

};



int main(int argc, const char * argv[]) {
    //tsizeof();
    tclassSizeof();
    return 0;
}

void tclassSizeof(){
    cout << "test class sizeof" << endl;
    //空类的大小为1
    cout << "sizeof TestA a=" << sizeof(TestA) << endl;
    //含有成员函数的类的大小8
    cout << "sizeof TestB =" << sizeof(TestB) << endl;

    //含有虚表 8+8
    cout << "sizeof TestC=" << sizeof(TestC) << endl;

    //简单继承
    cout << "sizeof TestD=" <<  sizeof(TestD) << endl;
    //TestE 继承了TestD 的虚表,他自己的虚函数也放在同一张虚表里面
    cout << "sizeof TestE=" <<  sizeof(TestE) << endl;

    cout << "sizeof TestE2=" <<  sizeof(TestE2) << endl;

    //虚继承,其实也是一样的
    cout << "sizeof TestF=" <<  sizeof(TestF) << endl;

    //多继承呢
    cout << "sizeof TestH=" <<  sizeof(TestH) << endl;
    cout << "sizeof TestH2=" <<  sizeof(TestH2) << endl;
    cout << "sizeof TestH3=" <<  sizeof(TestH3) << endl;

    //多继承中虚继承呢
    cout << "sizeof TestI=" <<  sizeof(TestI) << endl;
}

void tsizeof(){
    cout << "test sizeof " << endl;

    //sizeof是运算符,不是函数 定义
    cout << "int size=" << sizeof(int) << endl;

    //sizeof不能求得void类型的长度
    //cout << sizeof(tfunc1()) << endl;//错误
    cout << sizeof(tfunc2()) << endl;

    //sizeof能求得void类型的指针的长度
    void *p;
    cout << sizeof(p) << endl;

    //sizeof能求得静态分配内存的数组的长度
    char arr1[30];
    cout << sizeof(arr1) << endl;

    //sizeof不能求得动态分配的内存的大小
    char *arr2 = new char[30];
    cout << sizeof(arr2) << endl;

    //sizeof不能对不完整的数组求长度
    tsizeofArr1(arr1);

    //当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值
    int a = 11;
    int a2 = sizeof(a+2);
    cout << a2<<endl;

    //sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不执行函数体
    int a3 = sizeof(tfunc2());
    cout << a3 << endl;

    //sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和!
    //这个存在对齐
    cout << sizeof(st1) << endl;

    //sizeof不能用于求结构体的位域成员的大小,但是可以求得包含位域成员的结构体的大小!

    //cout << sizeof(st1.aFloat) << endl;//error

    //据说有一个不通过sizeof求int长度的题目可以利用地址间的减法求得
    int arr3[4];
    cout << (unsigned  long)&arr3[1] -(unsigned long) &arr3[0] << endl;


}

void tsizeofArr1(char arr[]){
    cout << "sizoeof arr[] "<<sizeof(arr) << endl;//error

}


void tfunc1(){

}

int tfunc2(){
    return 11231;
}


最后

以上就是谦让蚂蚁为你收集整理的cpp中使用sizeof和计算类占用空间的大小的全部内容,希望文章能够帮你解决cpp中使用sizeof和计算类占用空间的大小所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部