从具有虚函数的基类继承的类的sizeof

Pra*_*yot 3 c++ virtual-functions sizeof

对于以下代码片段.

/*This program demonstartes how a virtual table pointer 
 * adds to a size of a class*/

class A{

};

class X{
    public:
        void doNothing(){}
    private:
        char a;

};

class Z:public X {

    public:
        void doNothing(){}
    private:
        char z;

}; 

class Y{
    public:
        virtual void doNothing(){}
    private:
        char a;

};

class P:public Y {

    public:
        void doNothing(){}
    private:
        char pp[4];

};

int main(){
    A a;
    X x;
    Y y;
    Z z;
    P p;
    std::cout << "Size of A:" << sizeof(a) << std::endl;// Prints out 1
    std::cout << "Size of X:" << sizeof(x) << std::endl;//Prints out 1
    std::cout << "Size of Y:" << sizeof(y) << std::endl;//Prints 8
    std::cout << "Size of Z:" << sizeof(z) << std::endl;
//Prints 8 or 12 depending upon wether 4 bytes worth of storrage is used by Z data member.
    std::cout << "Size of P:" << sizeof(p) << std::endl;
    std::cout << "Size of int:" << sizeof(int) << std::endl;
    std::cout << "Size of int*:" << sizeof(int*) << std::endl;
    std::cout << "Size of long*:" << sizeof(long*) << std::endl;
    std::cout << "Size of long:" << sizeof(long) << std::endl;
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

我似乎注意到的行为是,每当实例化一个空类或从字节边界继承一个空类时都不会考虑(即:允许大小为1字节的对象),在其他每种情况下,对象大小似乎由字节边界.

这是什么原因?我问,因为在这一点上我猜.

Pav*_*aev 6

我不知道问题是什么,但我会做胡乱猜测和假设你的事实,混淆sizeof(A)==1,X从派生A添加一个char字段,但sizeof(X)==1(当你希望它是2 -一个是A,一个charX).

这被称为"空基类优化".在C/C++中,一个对象必须具有非零大小(ISO C++ 1.8 [intro.object]/5) - 这间接暗示每个对象都有一个不同的地址,尽管是工会 - 所以即使对于一个空类,它仍然必须至少1个字节.但是,当一个对象是另一个对象的基类子对象时,该限制被解除.因此,一个实例A必须至少为1个字节,但是当它A是另一个类的基类时,不再需要它,并且编译器可以完全摆脱该虚拟填充; 所以尺寸X只来自它的char领域.

  • C确实有对象.但是,在C和C++中,术语"对象"与OOP没有任何关系.从ISO C99第3节"术语,定义和符号",第3.14小节:"对象 - 执行环境中的数据存储区域,其内容可以表示值".ISO C++使用类似的定义.C++中的类的实例是"类类型的对象"(而"int"值是"非类型类型的对象"). (4认同)