从带有虚函数的基类继承的类上的 sizeof

发布于 2024-08-03 08:53:32 字数 1523 浏览 6 评论 0原文

对于以下代码片段。

/*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;

}

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

这是什么原因呢?我问,因为此时我正在猜测。

For the following code fragment.

/*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;

}

The behaviour I seem to notice is that whenever an empty class is instantiated or an empty class is inherited from byte boundaries are not considered(ie: an object of size 1 byte is allowed), in every other case object size seems to be determined by byte boundaries.

Whats the reason for this? I ask since at this point I am guessing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狠疯拽 2024-08-10 08:53:32

我不确定问题是什么,但我会大胆猜测并假设您对 sizeof(A)==1, X< /code> 派生自 A 添加一个 char 字段,但 sizeof(X)==1 (虽然您希望它是2 - 一个用于 A,一个用于 X 中的 char)。

这称为“空基类优化”。在 C/C++ 中,对象必须具有非零大小 (ISO C++ 1.8[intro.object]/5) - 这间接意味着每个对象都有一个不同的地址,尽管有联合 - 因此即使对于空类,它仍然必须至少为 1 个字节。但是,当一个对象是另一个对象的基类子对象时,此限制将被解除。因此,A 的实例本身必须至少为 1 个字节,但是当 A 是另一个类的基类时,就不再有此要求,并且编译器可以完全摆脱那个虚拟填充;因此 X 的大小仅来自其 char 字段。

I'm not sure what the question is about, but I'll make a wild guess and assume that you're confused by the fact that sizeof(A)==1, X derives from A adding a char field, and yet sizeof(X)==1 (while you'd expect it to be 2 - one for A, one for char in X).

This is known as "empty base class optimization". In C/C++, an object must have a non-zero size (ISO C++ 1.8[intro.object]/5) - this indirectly implies that every object has a distinct address, unions notwithstanding - so even for an empty class, it still has to be at least 1 byte. However, when an object is a base class subobject of another object, this restriction is lifted. Thus, an instance of A must be at least 1 byte by itself, but when A is a base class of another class, there's no requirement for that anymore, and the compiler can get rid of that dummy padding entirely; so the size of X comes only from its char field.

很酷又爱笑 2024-08-10 08:53:32

这是 Stroustrup 对空类大小的解释不能为零。至于为什么它是 1 个字节,而不是符合对齐边界的东西,我猜这取决于编译器。

Here is Stroustrup's explanation of why size of an empty class cannot be zero. As to why it is 1 byte, as opposed to something that conforms to the alignment boundaries, I would guess this depends on the compiler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文