C++ 我们如何证明声明虚函数的类比未声明虚函数的类多2字节,而未声明虚函数的类在子类中 类基 { 公众: 虚空a() { } }; 类子:公共基 { 公众: 作废 { } }; int main() { b1碱基; 儿童c1; cout
您可能正在尝试更多地查看实现内部以及编译器生成的内容 规则可以是这样的:当类或任何继承类中存在任何虚拟方法时,该类的对象必须存储所谓的“指向虚拟方法表的指针”,并且变长(现在通常为4或8字节) 在您的示例中,Base具有虚方法,因此它具有指向表的指针,并且从Base派生的所有类也必须具有该指针。这就是为什么您会看到相同大小的对象。尽管派生中没有“虚”,但a()从继承来看是虚拟的。这一定是因为如果其他代码通过基指针处理派生对象,它必须具有相同的接口,因此()始终被视为虚拟的C++ 我们如何证明声明虚函数的类比未声明虚函数的类多2字节,而未声明虚函数的类在子类中 类基 { 公众: 虚空a() { } }; 类子:公共基 { 公众: 作废 { } }; int main() { b1碱基; 儿童c1; cout,c++,C++,您可能正在尝试更多地查看实现内部以及编译器生成的内容 规则可以是这样的:当类或任何继承类中存在任何虚拟方法时,该类的对象必须存储所谓的“指向虚拟方法表的指针”,并且变长(现在通常为4或8字节) 在您的示例中,Base具有虚方法,因此它具有指向表的指针,并且从Base派生的所有类也必须具有该指针。这就是为什么您会看到相同大小的对象。尽管派生中没有“虚”,但a()从继承来看是虚拟的。这一定是因为如果其他代码通过基指针处理派生对象,它必须具有相同的接口,因此()始终被视为虚拟的 请注意,即使使用fin
请注意,即使使用final关键字也不会删除虚拟性。它只提供了额外的优化支持,但仍然无法删除虚拟性,因为同样的原因-稳定的API。首先,在32位的世界中(实际上现在大部分是64位),它可能会增加4个字节(或8个字节),如果有的话 尽管如此,
Child
还是没有理由大于base
首先,如果您从foo
是虚拟的类继承,即使您没有明确指定它,您的foo
也将是虚拟的(假设签名相同)
但最重要的是,虚拟函数的通常实现是通过指向共享vtable的指针来实现的,这意味着当您从“dumb”变为“dumb”时,您只需支付每个对象大小的一个指针类层次结构是多态的。这不是每个函数的开销,它也会影响所有派生类,因为编译器必须能够在给定一个指向派生对象的指针的情况下盲目调用正确的虚拟函数
(所有这些优化尚未完成)什么应该比两个字节大?为什么是两个字节?以及为什么您认为一个对象会比另一个对象大?请编辑您的问题以详细说明。您已经观察到某些编译器在某些情况下的行为。不同的编译器或不同的优化标志可能会产生不同的结果。总之,这只是一个问题实现细节,它不是标准化的,并且可以随时更改。不要依赖它。它肯定不应该超过两个字节。是否声明
Child::a()
虚拟与否无关,因为通过继承它已经是虚拟的。
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;
}