2011-12-01 139 views
3

我知道,「什麼時候指針和何時引用」或「通過引用傳遞參數或通過指針傳遞參數」這個問題已被多次詢問。然而,我的印象是,有幾次我讀到:「當你想修改它時,你應該通過指針傳遞一個對象到一個函數。如果最後一句話完全正確,有人可以說,解釋並說明理由嗎?傳遞一個對象作爲函數的參考或指針

換句話說,是不是可以通過引用修改對象?

回答

4

移動從一個存儲位置到另一個對象時,你應該,如果你想改變什麼指針指向傳遞一個對象作爲雙指針,例如:

void foo (obj **x) { 
    delete *x; 
    obj *y = (obj *) some_new_address; 
    *x = y; // change what x points to 
} 
... 
obj *x = new obj(); 
foo(&obj); 
// obj now points to another location 

與參考,你可以」這樣做。

+6

你可以通過引用傳遞一個指針:'void foo(obj *&x)' –

+0

好的,但是你仍然在傳遞一個指針。混合指針和引用語義可能會非常混亂,IMO。 –

+4

@BlagovestBuyukliev:嗯?這裏沒有什麼混雜。你正在引用一個指針。這比擁有指向指針的指針簡單得多。 – GManNickG

0

您可以通過引用和指針兩種方式修改對象。如果您不想修改,則可以使用const修飾符。

2

你引用的句子是規範性的,也就是說,它告訴你你應該做什麼,而不是你「能」或「不能」做什麼。因此,這是一個風格問題,需要辯論。我個人不接受它。

當然可以通過(非const)引用來修改對象。

0

要將變量作爲out參數傳遞,可以將它作爲參考以及指針傳遞。如果變量的存活時間超過範圍,只能使用指針。例如。從函數返回一個指針給被調用者。

在某些情況下,如果您無法在堆棧上分配內存,請使用指針並在堆上分配內存。也可以通過指針或引用將指針作爲out參數傳遞給函數。

1

當然,可以通過引用來修改對象。也許你引用的句子是關於C,它沒有引用?

的原則是這樣的:

  • 如果要修改參數,調用者可以不提供的,由指針傳遞(並傳遞NULL,0或nullptr爲沒有對象)。
  • 如果你想修改參數和對象必須傳遞給函數 - 通過引用傳遞。
  • 如果你不想修改說法,但主叫方可以不提供的,由const的指針傳遞
  • 否則,如果對象是昂貴的const引用複製傳球,如果不是,按值傳遞。
  • 新功能 - 如果您想在函數內部複製參數(例如,在構造函數中傳遞字符串以初始化字段)並且使用符合C++ 11的編譯器(支持移動構造函數),則按值傳遞。
4

爲方便起見,我將引用一個由函數修改爲「out-param」的參數。

Out-params可以作爲非const引用傳遞。沒有技術理由不這樣做。在標準庫中,例如,std::swap通過引用獲取兩個參數並修改兩者。

我曾經在一個風格指南中看過,必須通過指針而不是通過引用傳遞out-params。這背後的動機是,有些人想要一個函數調用出現按值傳遞對象,以保持對象不被修改。這使得他們更容易通過查看調用代碼來推斷代碼片段,而無需查看函數的實際功能。例如:

int foo(int a) { 
    return a + 1; 
} 
int bar(int &a) { 
    return ++a; 
} 

現在,鑑於int i = 0;,呼叫foo(i)bar(i)看起來完全一樣,但其中一人的行爲就像一個不錯的,簡單的C函數,而其他人使用過,通過引用修改i

有人[*]希望這些不同的事情,是在調用點明顯不同,所以他們更願意寫bar(&i),使之清楚,i可以修改[**]。基本上,他們更喜歡C++沒有非const引用作爲函數參數。

這些人想要做什麼並不一定是錯誤的。例如,您可以堅持使用std::swap,而不是使用std::iter_swap。但是大多數C++風格指南沒有任何這樣的規則。

[*]例如C程序員

[**]其實在我bar功能,a既是在-PARAM和出PARAM。他們的首選功能int bar(int *pa);在技術上沒有out-param,儘管爲了方便起見,他們可能會將pa(即i)的參數稱爲out-param,並且每個人都知道這意味着什麼。