2015-08-20 24 views
-2

參考這個問題,stackoverflow.com/q/14188612,有編譯器摺疊兩個對象的方法實例的情況嗎?C++非靜態方法摺疊

比方說,我們有一個私人的「無狀態」的方法add,不修改類成員以下類:

class Element 
{ 
public:   
    Class(int a, int b) : a_(a), b_(b) 
    { 
     c_ = add(a, b); 
    } 

private: 
    int add(int a, int b) 
    { 
     return a + b; 
    } 

private: 
    int a_; 
    int b_; 
    int c_; 
} 

int main(void) 
{ 
    Element a(1, 2); 
    Element b(3, 4); 
} 

可我們有時期望add實際上將被編譯爲static樣方法?或者,更清楚的是,a.add的地址等於b.addadd只存儲一次)。

這只是一個與理解編譯器優化有關的問題。

+0

該方法可能被內聯,這使得它是靜態的還是不相關的。但是你不能通過檢查地址來告訴它 - 你得到該函數的地址,然後編譯器會給你一個非內聯版本的地址,但可能永遠不會調用它。看看生成的代碼,它是唯一真相的來源。 –

+2

所有功能總是最多存儲一次。 – molbdnilo

回答

2

編譯器將總是產生一個二進制方法/ add功能,
獨立的有多少對象都有。其他任何東西都不是愚蠢的,而是不可能的:

編譯器不可能知道/計算在運行時只會從代碼中存在多少個對象。雖然可以用你的例子,但是更復雜的程序會根據運行時給出的輸入(鍵盤,文件...)實例化變量(或不變)。

請注意,模板可能導致超過一代,代碼中使用的每種模板類型都有一個(但代碼足以瞭解所有內容,並且與對象計數無關)。

0

當你在類定義中定義一個方法時,通常意味着該方法應該是內嵌到每個調用者。編譯器可以選擇不這樣做,但很多時候您可能會發現該方法根本不存在於您的輸出程序中(當然,在調試版本中並不是這樣)。

0

對於非內聯成員函數,所述標準說

須有在程序

非聯成員函數的至多一個定義有一個在C++ b.add沒有實體或a.add,您可以從中取得地址。 address-of操作符需要一個合格的id給C::m(...)這樣的成員函數來獲取函數的地址。在你的情況下,添加的地址是

auto ptr = &Element::add; 

並且獨立於任何實例。這給出了一個成員函數指針,它只能用來和一個對象一起調用函數,例如(a.*ptr)(0,1)(b.*ptr)(2,3)如果添加是公共方法。