const指標的引用

a694262054發表於2017-04-15

http://bbs.csdn.net/topics/310047017



const用法詳解

http://bbs.csdn.net/topics/310007610

1)對於非指標引用的形參,如fun1,傳入非const實參沒問題,如fun1(a)
但對於指標引用的形參,如fun,傳入非const實參卻有問題,如fun(b),
而傳入const實參就沒有問題,如fun(c),
為什麼?

2)另外,進行強制型別轉換,將非const實參轉換為const實參,
這種轉換(const int *)是錯誤的,如fun((const int *)d),
而必須這樣轉換fun((const int *&)e),
為什麼?

#include "stdafx.h"

void fun(const int *&)
{
}

void fun1(const int &)
{
}

int _tmain(int argc, _TCHAR* argv[])
{
int a = 0;
fun1(a);//ok

int *b = new int(0);
fun(b);//error
delete b;

const int *c = new int(0);
fun(c);//ok
delete c;

int *d = new int(0);
fun((const int *)d);//error
delete d;

int *e = new int(0);
fun((const int *&)e);//ok
delete e;

return 0;
}

1)對於指標引用的形參,如fun,傳入非const實參有問題,如fun(b), 
因為const int*& 這個引用的基本型別是const int*
非const引用只能引用相同型別的值 const int*和int*不一樣 而const引用則可以接受不同型別
如果fun改成void fun(const int * const &) 這樣就可以了

2)另外,進行強制型別轉換,將非const實參轉換為const實參, 
這種轉換(const int *)是錯誤的,如fun((const int *)d), 
而必須這樣轉換fun((const int *&)e), 
同上  型別不一致 改成void fun(const int * const &) 就沒錯了
const型別的引用不檢查型別一致性 修飾指標的時候要再宣告const才是const型別引用

const引用可以初始化為不同型別的物件或者右值(如字面值常量),但非const引用不可以。 

 程式碼如下:

// legal for const references only 
int i = 10; 
const int & ref = 42; 
const int & ref1 = r + i; 
double d = 3.14; 
const int &ref2 = d; 

以繫結到不同型別的ref2為例解釋原因,編譯器會把ref2相關的程式碼轉換如下: 
程式碼如下:

int temp = d; 
const int &ref2 = temp; // bind ref2 to temporary 

ref2實際上是繫結到一個臨時變數上,如果ref2不為const,那麼按道理就可以通過修改ref2而修改d的值,但實際上d並不會改變。所以為了避免這個問題,ref2只能是const。
非const引用只能繫結到與該引用同型別的物件,const引用則可以繫結到不同但相關的型別的物件或繫結到右值。 

http://blog.csdn.net/kelvin_yan/article/details/49508485

int * 是一種指向int型別的指標。
const int* 是指向const int型別的指標。
int *const 指向int型別的常量指標。
const int× &又是不同的type。(指向常量指標的引用)
int* const& 指向指標的常量引用。
const int* const& 指向常量指標的常量引用

當你呼叫
void fun(const int *&) ->要求引數的型別 : 指向const int型別的指標 的引用




int *b = new int(0); 
fun(b);//error


傳入的引數為int*, 如果要將int×轉成const int*& ,需要先將int*轉換為const int* 再將const int*轉換為const int* &,這需要兩個步驟的轉換。
實際上編譯器的 預設轉換最多隻能支援一個步驟的轉換!! 超過兩步以上的轉換,是不支援的。
當編譯器無法找到一步就能成功轉換的方法時,自然就會報錯了。


當你寫出一下的程式碼時,
int *d = new int(0); 
fun((const int *)d);//error 
delete d; 

當你使用fun((const int *)d)時,毫無疑問的是你引入了一個臨時變數,當你想引用一個臨時變數的時候,這個引用必須是const的,臨時變數必須被const引用。
而你函式的宣告,要求的是指向常量指標的引用,不是const引用,所以引用會失敗。


當然,如果你這樣呼叫:
int *e = new int(0); 
fun((const int *&)e);//ok 
delete e; 
這時候你創造了一個臨時的引用,但是變數型別和fun的宣告的引數型別是一致的,所以是ok的。

相關文章