本文介绍了如何确定虚拟基类和派生类的大小呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <iostream>
using namespace std;

class base1{};
class base2{virtual void show(){}};

class test1{    };
class test2{virtual void show(){}};

class derv1:public virtual base1{};
class derv12:public virtual base2{};

class derv2:public virtual base2, public test1{};
class derv22:public virtual base2, public virtual test1{};
class derv222:public virtual base2, public virtual test2{};

int main()
{
    cout<<"sizeof base1 = "<<sizeof(base1)<<endl;
    cout<<"sizeof base2 = "<<sizeof(base2)<<endl;
    cout<<"sizeof derv1 = "<<sizeof(derv1)<<endl;
    cout<<"sizeof derv12 = "<<sizeof(derv12)<<endl;

    cout<<"sizeof derv2 = "<<sizeof(derv2)<<endl;
    cout<<"sizeof derv22 = "<<sizeof(derv22)<<endl;
    cout<<"sizeof derv222 = "<<sizeof(derv222)<<endl;

}

输出:

sizeof base1 = 1
sizeof base2 = 4
sizeof derv1 = 4
sizeof derv12 = 8
sizeof derv2 = 8
sizeof derv22 = 8
sizeof derv222 = 12



我理解以下输出:

I understand following outputs:

sizeof base1 : 1 => empty class , size is 1. result is OK.

sizeof base2 : 4 => since class has a virtual function, it adds
                    a vitual pointer in each object of the class
                    ( 32 bit machine) , so added 4 bytes. Result is OK.

sizeof derv1 : 4 => base1 doesn't have  virtual function but since
                    derv1 is virtually derived from base1 ,added 4 bytes.
                    I think that each virtual base class
                    added a  pointer in object so i think Result is OK.

sizeof derv12: 8 => 4 bytes( from virtual pointer) + 4 bytes
                     (virtual base class ) = 8 bytes. Result is OK.

我在上述输出后开始混淆

My confusion starts after the above outputs

sizeof derv2  : 8 => 8 bytes( virtual pointer + virtually base class)
                    from base2 + 1 byte from test1 => 9 bytes and adds 3 padding
                    bytes gives 12 bytes (should print).
                     why "sizeof (test1)" is not adding in the output ??

sizeof derv22 : 8 => 8 bytes( virtual pointer + virtually base class)
                    from base2 + 4 byte (virtually base class)
                    from test1  => 12 bytes (should print)

                    why 4 bytes from  test1 (virtual base class)  is not added
                    in the output?? In the  size of(derv1 ) also has
                    a virtual base class( base1) and out put is 4 bytes means
                    they added 4 bytes in the output.

sizeof derv222: 12 => 12 bytes( virtual pointer + virtually derived)
                      from base2 + 8 byte( virtual pointer + virtually derived)
                      from test2  => 16 bytes (should print)

我缺少某个字符或这些大小是系统依赖还是其他什么? sizeof(base1)和<$ c的原因是什么?

Am I missing somethineg or these sizes are system dependent or any thing else??

推荐答案

$ c> sizeof(test1)都是单独的,以防止大多数派生对象的大小为0.这是所有的标准禁止。基类子对象允许具有大小0(即,允许不占用字节),因此添加 base1 作为基础不一定必须向类的大小添加任何内容。

The reason that sizeof(base1) and sizeof(test1) are 1 is solely to prevent a most-derived object from having size 0. That's all the standard forbids. Base class sub-objects are allowed to have size 0 (that is, allowed to occupy no bytes), and hence adding base1 as a base doesn't necessarily have to add anything to the size of the class.

您的编译器所做的优化,不会为类型的子对象分配任何字节是一个空类,被称为空基类优化。标准不要求实施应用它,但是实现不适合严重的工作。

The optimization your compiler has made, not allocating any bytes for a base-class sub-object whose type is an empty class, is called the "empty base class optimization". It's not required by the standard that the implementation apply it, but an implementation that didn't might not be considered fit for serious work.

我认为 derv22 有点类似 - 如果编译器能够使用一个额外的指针处理两个虚拟基类,那么它有权这样做。因此,你可能只需要支付一次,而不是支付每个虚拟基地。这可能取决于编译器和类之间的确切关系,虽然,我从来没有调查过不同的实现,看看是否和什么时候他们被迫添加多个指针值得开销。

I think derv22 is somewhat similar - if the compiler is capable of dealing with two virtual base classes using a single extra pointer, then it's entitled to do so. Hence, you might only have to "pay" once, rather then "paying" per virtual base. That could depend on the compiler and on the exact relationships between the classes, though, I've never surveyed different implementations to see if and when they're forced to add multiple pointers worth of overhead.

显然, derv222 已经做到了,至少对于你的编译器。我想这是因为 base2 test2 基类子对象需要单独的vtable指针。如果你考虑当你 static_cast a derv222 * 作为指向一个基地或另一个基地的指针时会发生什么,可能不奇怪 - 两个结果都需要能够对它们调用 show(),并调用不同的函数(虽然 show 函数目前什么也不做)。我不知道是否可能另一个编译器实现这个继承在8个字节 - 一件事继承不是使用vtables实现

Apparently derv222 has done it, though, at least for your compiler. I suppose that this is because the base2 and test2 base class sub-objects need separate vtable pointers. Probably not that surprising if you consider what happens when you static_cast a derv222* as a pointer to one base or the other - both results need to be capable of having show() called on them, and calling different functions (albeit the show functions currently do nothing). I'm not sure whether it would be possible for another compiler to implement this inheritance in 8 bytes -- for one thing inheritance doesn't have to be implemented using vtables.

这篇关于如何确定虚拟基类和派生类的大小呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:16
查看更多