指標或引用(有人稱之為別名)。編譯器真的在意嗎?
讓我們做一個簡單的實驗,我相信這能幫助任何想理解指標和引用的人。
讓我們宣告兩種簡單的函式版本
但暫時我們只使用 int& 版本。
1 2
|
//void some_function(int* i){cout << "\nvalue is " << *i << endl;};
void some_function(int& i){cout << "\nvalue is " << i << endl;};
|
區別在於一個接受整數的引用,而另一個
接受指標。到目前為止一切都很簡單,現在讓我們呼叫函式使用
指標。
初始化變數。這只是為了讓我們之後需要重新轉換 fp
,我的意思是它除了在這裡的例子之外沒有其他意義。
所以現在 fp 是一個指向某個位元組的指標。它不知道自己指向
一個函數了。
1 2
|
char* fp = reinterpret_cast<char*>(&some_function);
int ii = 5;
|
第一次呼叫 some_function,重新轉換 fp
1 2
|
reinterpret_cast<void(*)(int&)>(fp)(ii);
|
這將輸出 ii 中的值,即 5。
所以沒問題,一切都很簡單。
第二次呼叫 some_function
現在讓我們稍微改動一下來呼叫它
1 2
|
reinterpret_cast<void(*)(int*)>(fp)(&ii);
|
這當然會輸出相同的 5,因為它呼叫
的是同一個函式。但請注意,我使用了 int* 來轉換指標
而不是 int&,而我們正在使用的函式宣告是
int& 版本。
在第一次呼叫中,我們使用了正確的型別進行轉換,而且我們不用
透過 &ii 來呼叫。在第二種情況下,因為我們使用了 int* 來轉換
,我們需要透過 &ii 來呼叫,將其轉換為一個 POINTER。
我認為這個簡單的例子表明,當編譯器看到一個引用,並且有人用不同的簽名呼叫它,比如
int*,因為它那時已經將 int& 改為了到處都是 int*,所以它並不太在意。
換句話說,就編譯器而言,它只看到
|
void some_function(int* i){cout << "\nvalue is " << *i << endl;};
|
即使你寫成
|
void some_function(int& i){cout << "\nvalue is " << i << endl;};
|
而使用指標呼叫引用的呼叫將被更改為
使用指標的呼叫。
你可以嘗試註釋掉程式碼,用兩種方式呼叫函式,看看它們是如何工作的。
嗯,我希望這對某人有所幫助,或者至少讓他們覺得有趣。