2015-02-10 76 views
-2

编译器如何处理一个完整的空函数在运行时表现?调用一个空的基类函数,在编译时会发生什么?

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

示例用法:

int main() 
{ 

    Base b; 
    b.execute(); 

    return 0; 

} 

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

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

由于所需的灵活性,并保持尽可能简单的梦想,我想出了一个共享Base类的PropertiesComponent类。请参阅下面的代码块。

但是,类Base包含功能​​,并在分配给该类的所有属性和组件中在最终类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语句可以确定调用执行函数。

+0

我低估了这一点,因为它是另一个“我盯着一些代码并对编译器工作做出假设” - 问题。所有这些问题的唯一答案:尽可能编写最合理和可读的代码,然后通过测量优化您发现速度太慢的问题。 – 2015-02-10 22:27:03

+1

如果我理解了你没有问的问题,那么:在从Base派生的层次结构中添加更多层是否会产生额外的运行时成本?如果只有最派生类实际上在execute()中做了任何事情,答案是否定的。如果它调用一个父类'执行并且该函数在另一个翻译单元中,那么它会引起一个额外的函数调用。 – qeadz 2015-02-10 22:31:41

+0

@qeadz:不会退出,尽管你的回答确实消除了我在获得这个问题的输入之后所针对的另一个不安全感。 – Ruijter 2015-02-10 22:55:00

回答

1

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

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

但是,一般的规则是停止假设并开始测量,具有真实数据和实际使用模式。今天的性能预测非常复杂(几乎不可能非常复杂),因为CPU本身就是小小的复杂怪物,而且其中有很多。你需要测试以发现时间花在哪里......猜测不能很好地工作。

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

+0

该系统的上下文能够在运行时为类添加功能性。不同子类的数量是未定义的。它应该甚至能够通过链接到一个新的共享库来在稍后阶段添加更多内容。 ---认为现在是时候了解inline关键词了。 – Ruijter 2015-02-10 23:04:37

+0

@Ruijter:为了创建一个“开放”系统,虚拟函数是最好的选择......但是这种方法仍然需要重新编译程序(或者至少动态加载一个库:C++标准没有涉及的东西,但是为此大多数平台提供特定的解决方案)。另一种提供真正运行时可扩展性的选项(即为程序添加新功能而不停止它)是实现/嵌入完整的扩展语言;更复杂但可行。 – 6502 2015-02-11 07:10:15

相关问题