空类的大小

#define _CRT_SRCURE_NO_WARNINGS
#include
#include
using namespace std;

class x {};  
class y :public virtual x {};
class z :public virtual x {};
class a :public y, public z {};
void main1()
{
    cout << sizeof(x) << ends    //1
        << sizeof(y) << ends     //4
        << sizeof(z) << ends     //4
        << sizeof(a) << endl;    //8

    /*class x {}; 实质上不为空,编译器安插进去了一个char,
    这就使得这个class的两个object得以在内存中配置独一无二的
    地址*/
    x x0, x1;
    cout << &x0 << ends << &x1 << endl;  //两者不同
    cout << sizeof(x0) << endl;          //1
    /*
    class y :public virtual x {};   4   【有可能是8】
    class z :public virtual x {};   4   【有可能是8】
    y和z大小因素:
    1、语言本身造成的额外负担:当语言支持virtual base classes时,
    就会导致一些额外负担。在derived class中,这个额外负担反应在
    某种形式的指针上,它或者指向virtual base class subobject,或者
    指向一个相关表格:表格中存放的如果不是virtual base class subobject
    的地址就是其偏移量。
    2、编译器对于特殊情况所提供的优化处理:vritual base class X subobject
    的1byte大小也出现在class Y和Z之上。传统上它被放在derived class
    的固定[不变动]部分的尾端。有些编译器会对empty virtual base class
    提供特殊支持。
    3、对齐限制:32位机器4字节对齐。因此结果可能是8
    空虚基类:提供一个虚接口,没有定义任何数据。某些编译器对此提供了
    特殊处理:一个空虚基类被视为派生类对象最开头的一部分,也就是它并
    没有花费任何的额外空间,这就节省了上诉2点的1bype和对其的3byte,因此4
    */

    y y0;  z z0;
    cout << sizeof(y0) << ends   //4
        << sizeof(z0) << endl;   //4

    a a0;
    cout << sizeof(a0) << endl;   //8

    system("pause");
}

/*
一个类的数据成员可以表现这个类在程序执行时的某种状态:静态
数据成员放置的是“整个class”感兴趣的数据,非静态数据成员放置的
是“个别的类对象”感兴趣的数据。

非静态数据成员:把数据直接存放在每一个类对象中。
对于继承而来的非静态数据成员:把数据直接存放在每一个派生类的对象中。

静态数据成员:被放置在程序的一个全局数据段中,不会影响个别的类对象的大小/
在程序中,不管该class有多少个对象[直接/派生],静态数据成员永远只存在一份实体

每一个类对象必须有足够大小容纳它的所有非静态数据成员[大于等于]:
1、编译器可能会自动加上额外的数据成员,用以支持vritual特性
2、对齐需要

*/
class x1 { static int xx; };
class y1 :public virtual x1 { };
class z1 :public virtual x1 {};
class a1 :public y1, public z1 {};

void main()
{
    cout << sizeof(x1) << ends; //静态数据放在全局区,和对象和类每关系。只是类可以使用这个全局静态数据
    cout << sizeof(a1);   //8
    system("pause");
}

你可能感兴趣的:(#,C++)