看一道C++面試題:
給出下述代碼,分析編譯運行的結果,並提供3個選項: A.編譯錯誤 B.編譯成功,運行時程序崩潰 C.編譯運行正常,輸出10
class A
{
private:
int value;
public:
A(int n){ value = n;}
A(A other){ value = other.value; }
void Print(){ std::cout << value << std::endl; }
};
int main()
{
A a = 10;
A b = a;
b.Print();
return 0;
}
剛開始看到題的時候,我並沒有看出貓膩,說實話,自己在C++這里還是個菜菜菜菜菜,如果要我選我會十分忐忑的選C,忐忑是因為知道C肯定不是對的,選C是因為自己又太菜看不出貓膩。
OK,正確答案是編譯出錯。
現在來解析一下這里的考點:拷貝構造函數傳參問題,熟悉C++語法的大佬們都知道在拷貝構造函數A(A other)中有一個很明顯的錯誤,就是形參,正確的形參應該是 const A& other,而不是 A other。
1.除了常量引用能節省空間外,這兩個形參有什么區別嗎?
有區別,區別很大。我們都知道將實參傳遞給實參相當於把實參的值賦給形參。執行A b = a;時,會調用 b的拷貝構造函數,此時實參 a會被賦值給形參 other,相當於語句 A other = a; 又會繼續調用other的拷貝構造函數,將 a賦值給對象other的拷貝構造函數的形參other,如此一來,就會形成一個遞歸操作而且沒有結束條件,造成堆棧溢出。而C++不會允許這種錯誤發生,因此 A other做形參會編譯錯誤。
而const A& other就不一樣,以引用做形參,並不會調用拷貝構造函數,所以正確。
2.為啥要加const
如果在函數中不會改變引用參數對象的值,加不加const無所謂,但是為了程序的安全性着想,加上const會禁止更改引用參數對象。