调用一个空的基类函数,编译时会发生什么?

时间:2015-02-10 22:23:23

标签: c++ visual-studio-2013 compiler-optimization

编译器如何处理完整的空函数在运行时的行为?

class Base
{
    public:
    virtual void execute(){ /* always empty */ }
};

示例用法:

int main()
{

    Base b;
    b.execute();

    return 0;

}

创建一个实体系统,该系统应该能够拥有仅保存数据的子类。这些被称为Properties。有些人需要有一个操作函数来结束数据。这些类称为Component

目的是能够在运行时向类添加功能,甚至可以在以后使用其他共享库添加功能。

由于所需的灵活性以及希望尽可能保持简单,我想出了BaseProperties类的共享Component课程。请参阅下面的代码块。

但是,类Base包含函数execute(),并在最终类Container中为分配给该类的所有属性和组件调用。

PropertyComponent完全分成两个不同的身份可能会更好,但是他们会相互依赖,例如属性可以是变换(位置,缩放,四元数,矩阵),而组件可以是变换中四元数的动画。

#include <vector>

class Base
{
    public:
    virtual void execute(){ /* always empty */ }
};

class Property // as manny will be
: public Base
{
    public:
    /* specifics */
};

class Component // as manny will be
: public Base
{
    public:
    /* specifics */
    virtual void execute(){ /* do whatever */ }
};

class Container
{
    public:
    std::vector<Base*> list;
    virtual void execute()
    {
        std::vector<Base>::iterator iterator = list.begin(), end = list.end();
        while( iterator != end )
            ( *iterator )->execute();
    }

}

除了生成二进制文件之外,我不知道编译器实际上做了什么,我认为它不会相当于一行一行的调试会话。

编译器如何处理这样一个空函数,将function execute();作为第一个声明移动到类Component会更好。然后将enum{ Property, Component };添加到类Property,以便if语句可以确定调用执行函数。

1 个答案:

答案 0 :(得分:1)

虚拟函数调用非常便宜,但根据不同子类的数量,交换机可能更快(原因是交换机不会创建另一个执行上下文),但当然灵活性要低得多。如果要实现execute方法的主体,尤其如此,它们中的大多数将共享部分处理和数据访问(例如,对于虚拟机的不同指令),因为其中的一部分可以缓存出来循环。

将属性保存在同一容器中并使用空的execute方法保留它对我来说似乎不合理,但这可能只是缺乏正在解决的问题的上下文。

然而,一般规则是停止假设并开始测量,具有真实数据和实际使用模式。今天的性能预测非常复杂(几乎不可能复杂),因为CPU本身就是复杂的怪物,而且有很多。你需要进行测试才能找到花费的时间......猜测并没有那么好。

我的第一种方法是使用虚函数并尽可能简化事物。如果我测量的是调度开销是问题并且在其他区域没有更大的搜索值,那么只能在循环中内联这些函数。