1. 程式人生 > 其它 >對於by reference的函式形參的一些很容易錯的點:

對於by reference的函式形參的一些很容易錯的點:

技術標籤:C++

這一塊內容迷茫了很久一直不清楚,今天搞透作為記錄:

  • 對於by reference的函式形參,如果確實該函式不會修改引用繫結的內容,就必須宣告為by reference to const,這裡是必須,不是建議,儘管在很多情況下並不會出問題,只是因為沒涉及到下面這些case:
  • 先說結論:
    宣告為by reference to const而不是by reference的作用如下:
    1.使用const可以避免無意中修改資料的程式設計錯誤
    2.使用const使函式能夠處理const和非const實參,否則將只能接受非const資料
    3.使用const引用使函式能夠正確生成並使用臨時變數
  • 前兩點很清楚了就不再贅述,下面示例是用於解釋第三點的
#include <iostream>
#include <string>

using namespace std;

class B{
public:
	explicit B(string p = "lixu") : s(p){}
	string s;
};


void f( B& b){ 
	cout << b.s << endl;
}


int main() {
	//1. 在這種情況下呼叫f,傳入f的是一個右值的B型別的臨時變數,如果f的形參不是const,就相當於將一個non-const的左值引用繫結到一個右值臨時變數
//上,但右值被不能修改,如果這一步可以通過的話,就可以通過non-const的左值引用去修改一個右值了,顯然這一步不能這樣。 //2. 但f的形參若宣告為const,就可以通過了,因為即使const左值引用繫結這個右值臨時變數,也不用擔心這個引用會去修改那個右值,因此可以通過。 f(B("haha")); return 0; }

如果f的形參處宣告為B& b,就會報錯:
在這裡插入圖片描述

  • 上面示例中還有可以探討的點:
    結論是:編譯器為我們執行一步隱式型別轉換;
    由於B的建構函式宣告為explicit,但即使把explicit去掉,呼叫時仍然可能通不過
//因為字面值常量“haha”到string本身是non-explicit的,因此從“haha”到string是隱式型別轉換;
//如果把B的建構函式也宣告為non-explicit,那麼從string到B也是隱式型別轉換; //因此從“haha”到B需要經過兩步隱式型別轉換,但編譯器只會為我們執行一步,這也顯示了一點,編譯器不會為我們做超出預期的太多隱式的事情; f("haha");//錯誤; //要想通過編譯,只需我們顯式完成其中一步即可 f(string("haha")); //正確:"haha"到string顯式轉換,string到B隱式轉換 f(B("haha")); //正確:"haha"到string隱式轉換,string到B顯式轉換