我们怎样才能证明声明了虚函数的类是多于2个字节而不是声明的,这是在子类中

时间:2017-12-13 06:38:25

标签: c++

class Base
{

public:
    virtual void a()
    {

    }
};
class Child:public Base
{
    public:
     void a()
    {

    }
};
int main()
{
    Base b1;
    Child c1;
    cout<<sizeof(b1)<<endl;
    cout<<sizeof(c1);
    return 0;
}

尽管对象b1c1的大小返回相同,但这是4个字节。相反,如果声明了关键字virtual,那么它应该多2个字节。

2 个答案:

答案 0 :(得分:0)

您可能正试图在实现中查看更多内容以及编译器生成的内容......

规则可能如下:当类中有任何虚拟方法或任何INHERITED CLASS时,该类的对象必须存储所谓的“指向虚拟方法表的指针”并且变得更长(现在通常是4或8个字节)。

在您的示例中 Base 具有虚方法,因此它具有指向表的指针,并且从 Base 派生的所有类必须也具有此指针。这就是为什么你看到相同大小的对象。尽管 Derived 中没有“虚拟”,但 a()是继承的虚拟。它必须是因为如果其他代码通过 Base 指针与 Derived 对象一起工作,它必须具有相同的接口,因此 a()是被视为虚拟。

请注意,即使使用 final 关键字也不会删除虚拟化。它只为优化提供了额外的支持,但由于同样的原因 - 无法移除虚拟性 - 稳定的API。

答案 1 :(得分:0)

首先,在一个32位的世界中(现在实际上大多数是64位),如果有的话,可能会增加4个字节(或8个字节)。

但是,Child没有理由比foo大。

首先,如果您从foo是虚拟的类继承,即使您的 select * from maintable where ( case when @type ='ALL' then 1=1) else type in (select data from SplitString(@type,',')) end) 也将是虚拟的(假设相同的签名),即使您没有&# 39; t明确指定它。

但最重要的是,虚拟函数的通常实现是通过指向共享vtable的指针,这意味着当你从&#34; dumb&#34出发时,你支付的唯一每对象大小惩罚是一个指针;类层次结构到多态的。它不是每个函数的成本,它也影响所有派生类,因为编译器必须能够在给定指向派生对象的指针的情况下盲目地调用正确的虚函数。

(所有这些优化都没有见到)