一個以引用作爲參數的函數無法接收一個常量作爲實參

亞信的面試題如下:

#include "iostream"
#include "string"
using namespace std;
class Class1{
public:
 Class1(char *){};
};
void f(Class1 &){};
void main()
{
 f("string");
}

請指出上述代碼的錯誤,並改正之。

直接編譯上述代碼,得到的結果是:

  “cannot convert parameter 1 from 'const char [7]' to 'Class1 &'”,意思就是無法將一個常字符數組轉換爲一個Class1的引用。

我們已經有Class1的構造函數,f是f能夠將常字符數組隱式地轉換爲一個Class1的。那麼問題肯定就出現在“引用”上了。

讓我們來看一下f在接收到“string”這個常字符串的時候後做了哪些工作,首先是調用class1的構造函數,在臨時變量區生成一個class1的臨時變量(下文用A來稱呼它),並用“string”初始化之。

         重點是,這個臨時變量的是一個常量,而f函數的形參是一個class1的引用,一個變量的引用就是變量的別名。實質上,變量名和引用名都指向同一段內存單元。如果形參爲變量的引用名,實參爲變量名,則在調用函數進行虛實結合時,並不是爲形參另外開闢一個存儲空間(常稱爲建立實參的一個拷貝),而是把實參變量的地址傳給形參(引用名),這樣引用名也指向實參變量。如果我們允許將A作爲class1的引用傳遞給f,那麼f就能夠在它的函數體裏面去修改A的值了,這個與A是常量的這個屬性相矛盾。

        所以要改正這段代碼有兩條途徑,第一,把f的形參變爲class1 而不是class1 &, 即“void f(Class1 ){}”這時,系統在傳遞參數給f的時候,就會另外開闢一個空間保存A的一個副本,在f中對形參的修改都是對這個副本的修改,而A則不會有任何改變,也就不會與A是常量這個屬性相矛盾了。第二,就是把f的形參寫成const Class1 &,即"void f(const Class1 &){}"這是系統在傳遞參數給f的時候,沒有另外開闢一個空間,而是讓形參指向實參A的內存區域,但是由於形參也是const的,所以在f函數體內,系統不允許對A的任何修改,這樣也不會與A是常量這個屬性相矛盾了。

 

 

 

 

 

 

發佈了44 篇原創文章 · 獲贊 10 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章