2012-08-24 32 views
4
struct S { 
    S() {} 
    S (const S &) = delete; 
}; 

void f1 (S s) {} 
void f2 (S &s) {} 

int main() { 
    S s; 

    f2(s); 
} 

由於S(S &s)被刪除,爲什麼使用f2因爲當它宣佈它通過在爭論未拋出錯誤S &s?當我使用f1(s)時,它會引發錯誤。我查看了刪除函數的定義,我認爲這會拋出一個錯誤,但事實並非如此。爲什麼?爲什麼使用這個刪除的函數有效?

回答

9

讓我們來看看S

struct S { 
    S() {}     // default constructor 
    S (const S &) = delete; // copy-constructor 
}; 

你在這裏有什麼是可以建造的類型,但不能複製。

現在讓我們來看看你的函數:

void f1 (S s1) {} // creates a local copy of its parameter 
void f2 (S &s2) {} // takes a reference to the parameter 

當你調用f1(s),該函數試圖創建的s副本 - 而你的類型S禁止複製 - 這就是爲什麼這是行不通的。

當你調用f2(s),該函數創建其參數的引用 - 所以無論你做什麼內部f2s2直接對原始對象s。一個班級無法阻止任何人蔘考該對象。

+0

讓我感到困惑的是,當我看到'S(const S&)= delete'時,我想:*當我看到'f2(S&s2)'工作時,不要讓用戶做任何事情,比如* S&s'我不明白這個邏輯。 – 0x499602D2

+0

是的,我可以看到這可能會令人困惑......但是您必須記住,構造函數(特別是那些具有單參數的構造函數)是_special_。 – Fiktik

10

因爲按引用傳遞不會創建副本(這是f2使用的)。

f1另一方面,採取傳遞值參數,它進行復制。

+0

因此'S(S&S)= delete;'意味着不允許通過引用傳遞? –

+0

@ user6607不行,因爲通過引用工作。它不允許傳遞值。 –

+0

@LuchianGirgore好吧,但它看起來像完全相反... –