【问题标题】:Why doesn't compiler make a virtual function non virtual when it is possible?为什么编译器在可能的情况下不将虚函数设为非虚函数?
【发布时间】:2013-06-28 21:52:57
【问题描述】:
class A{
     void virtual a(){}
};
int main() { 
    std::cout<<sizeof(A);
}

在上述情况下,为什么编译器不将函数设为非虚拟函数并节省分配给它的空间。有没有不这样做的具体原因?

我使用的是 gcc 4.7 编译器,如果它是特定于编译器的。

【问题讨论】:

  • 因为编译器无法准确判断你是否使用了动态调度机制。它不能仅仅通过检查当前的 TU 来假设您不这样做。
  • 在一个相关问题上,值得注意的是,如今大多数编译器都可以内联虚函数,因为它可以在编译时确定正在调用哪个虚函数的重载。

标签: c++ oop gcc virtual-functions


【解决方案1】:

因为您可以在单独的翻译模块中创建派生类。

理论上这可以在链接时解决,但这会涉及大量工作,因此在实践中不会发生 (AFAIK)。

【讨论】:

  • 有了动态库,即使是 LTO 也不能排除子类可能进入画面。至少在 LTO 也应用于动态链接器之前 ;-)
【解决方案2】:

编译器本身可能不会这样做,因为它不知道其他文件中的内容。

链接器可能能够做到这一点,但不能保证 A 的后代版本不存在于某处并且将被加载到单独的模块中。

【讨论】:

    【解决方案3】:

    你确定你写的是真的吗?您在优化构建方面的证明是什么?

    我的观察是,如果程序确实包含创建 A 的单个实例的代码,则 VMT 不会与程序链接,并且也不会使用包括虚拟函数在内的函数。

    【讨论】:

    • 是的,我运行了程序,输出是8
    • 是的,但是 8 是什么?或者您的意思是为什么实例中包含指向 VMT 的指针的问题?如果是这样,请编辑问题。
    • 不,我的意思是我发布的内容。无论如何 Oli Charlesworth 已经给出了答案。
    • 所以你认为8和类中的函数a()有什么关系?
    • 是的,去掉'virtual',输出为1(和空类一样)
    猜你喜欢
    • 2015-12-12
    • 2010-10-27
    • 2017-10-30
    • 2012-07-20
    • 1970-01-01
    • 2010-09-12
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多