Class内存小记

首先看代码示例:

class ClassA {
public:
    virtual ~ClassA(){};
    virtual void FunctionA(){};
};

class ClassB:public ClassA {
public:
    virtual void FunctionB(){};
};

class ClassC : public ClassB {
public:
};
cout << sizeof(ClassA) << sizeof(ClassB) << sizeof(ClassC);//结果是444
struct A{
    int a;
    char b;
}
struct B:A{
    char a;
}
sizeof(sizeof(B));//12,这里并不是8
//这里为了简化,使用struct。在C++中,struct和class除了两点之外完全相同
//1.内部成员默认访问权限不同,struct是public,class是private
//2.派生类默认继承权限不同,struct是public,class是private
struct C {
    C(){}
    ~C(){}
};
sizeof(C);//1,
1.对象内存

解释:

    • ClassA在这里等同对一个该类的对象求sizeof
    • 无论类内部有多少个虚函数,在类内存内部只存虚函数表的地址(4 bytes)
    • member function是不占用空间的,无论你仅在类内部声明,还是在内部实现
    • 数据成员按照其类型占用相应的空间(int:4bytes, double:8bytes, 64位环境另当别论。注意,这里的64位不是指操作系统是64位的,而是你的编译环境是多少位的。如VS2013中通过配置管理器可以切换win32和x64)
    • 即使ClassB中存在与ClassA中同名的变量,从作用域角度讲,ClassA中的变量会被隐藏,但是这不能掩盖ClassA中的变量被继承的事实,所以ClassA还是会占用两个该变量的内存。
    • 注意内存对齐。假如我在ClassA中声明一个char ch;(无论在public或者private中)那么结果就会变成888。char类型应该占用一个bytes的空间,但是因为内存对齐,使得申请的空间必须是4bytes的倍数(为了提升访问速度);所以类推,假如在ClassA中声明char ch1; char ch;那么结果还是888。
    • 注意继承。如上条所示,基类的成员变量的访问权限无论是private还是public,派生类都会继承,只不过是能不能访问的问题。
    • static int a;这样的a成员是不会占用空间的。const int a = 0这样的a成员是占用空间的
    2.指针地址
    ClassC c;
    ClassA pa = &c;
    ClassB pb = &c;
    ClaasC pc = &c;

    那么这三个指针所存地址相等。这里写图片描述
    如图所示,这就是ClassC的内存图,由于ClassC直接继承了ClassB,间接继承了ClassA,所以C中完全包含了A,B。将c对象的地址赋给三个类类型的指针,就是让这三个指针指向自己对象的寻函数表地址,所以都指向了ClassC内存的首地址,所以三个指针的值相同。

    假设还是有A,B,C三个类,但是更改继承关系。代码如下:

    class ClassA {
    public:
        virtual ~ClassA(){};
        virtual void FunctionA(){};
    };
    
    class ClassB {
    public:
        virtual void FunctionB(){};
    };
    
    class ClassC : public ClassA,public ClassB {
    public:
    };

    那么此时三个指针的关系是,pa == pb == pc
    如果改变继承顺序,如下:

    class ClassC : public ClassB,public ClassA {
    public:
    };

    那么pb == pc
    道理相同。

    3.enum内存分配
    class A {
        enum{red,green,yellow};
    }
    class B {
        enum{red, yellow, green}color;
    }
    sizeof(A);//1,因为enum没有实例化
    sizeof(B);//4,相当于一个int
    4.union内存分配

    union的特点就是内存覆盖,其内部的变量共同使用一块内存,但是每次只能为其中的一个变量赋值。

    class A {
        union {
            char buff[13];
            int size;
        }
    }
    class B {
        union {
            char buff[3];
            int size;
        }
    }
    sizeof(A);//16,因为char空间是13bytes大于int的4bytes,所以分配13bytes
    sizeof(B);//4,这里char是3bytes,较小,所以分配4bytes
    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值