2011-11-02 55 views
23

面試官向我展示了一個這樣的代碼,並問我是否會編譯並給出我的推理。我非常肯定地告訴他,它不會編譯,因爲10是一個常量,您不能將常量分配給非const引用(如int & b = 10不會編譯),_a也是一個臨時變量,它是同樣也考慮了const,你不能使用非const引用來引用const變量。爲什麼編譯?期望「不能將常量分配給非const引用」

但是,在我回家後,我發現它完全可以編譯所有可能的編譯器。另外,我沒有得到這份工作。我的理解有哪些部分出錯?

class A { 
    int& a; 
public: 
    A(int _a):a(_a) {} 
}; 

int main() { 
    A a(10); 
}  
+24

您採訪的位置是什麼?如果除了構建C++解析器之外的任何東西,我都會說需要知道C++的每一個隱藏的角落,比如這個,這可能是荒謬的。 – Mysticial

+11

我給人的印象是,面試官過分強調了解語言的晦澀難懂的一面,並且缺乏足夠的設計技巧和最佳實踐。 –

+1

@Mysticial:對於新開發人員來說,這是一個常見的錯誤,因爲這個代碼起初看起來很有效,但會在隨機點(在函數調用之後)失敗。 – Dani

回答

27

沒有與此代碼一個const的「轉讓」 ......

該代碼調用它接受一個int構造函數,進而調用int&的初始化。當您假設它代表int& b = 10時,您跳過了編譯器所看到的幾個步驟,而它更像_a = 10; int& a = _a;。它編譯,但是完全沒有你想要使用的(綁定引用到堆棧,以後會導致未定義的行爲/損壞)...

7

這將綁定到堆棧,因爲函數參數可以綁定到參考。然而這是不安全的,並且會在某些時候導致未定義的行爲和堆棧損壞。

12

_a是一個臨時變量,它也被認爲是常量,

錯誤。在構造函數主體和初始化列表的範圍內,它並不是暫時的。它是一個左值和函數參數 - 它遠遠超出了您對整個函數體的單獨使用。

另外,rvalues和const與對方完全沒有任何關係,只不過在C++ 03中,您不能將非常量引用綁定到右值。例如,你可以在rvalues上調用大量的非const函數。

此代碼是直接等同於

int main() { 
    int i = 10; 
    int& x = i; 
} 

隨着參與與它在一類是壽命問題,增加樂趣。

4

這個概率有兩個問題。

q1)是否應該編譯?

Ans:它會編譯,因爲這裏的a指的是_a,這不是編譯器頭疼怎麼會得到數據。

q2)它是正確的代碼?我的意思是否會有任何運行時錯誤?

Ans:這不是正確的代碼。這裏a指的是_a,它是堆棧變量。因此,如果使用類A對象訪問引用變量a,則輸出將不可預知。 讓我們的例子,如下所示:

class A { 
public: 
    int& a; 

    A(int _a):a(_a) {} 
}; 

int main() { 
    A a(10); 
    A a1(11); 
    cout << a.a; 
}  

見的輸出。輸出是不可預測的,因爲您正嘗試訪問引用構造函數的堆棧變量的引用變量a

相關問題