2015-02-10 79 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

相關問題