2011-02-09 52 views
2

我想知道哪一個更好的傳遞地址指針的這兩個實現。第一個數據交換是否在第二個數據交換中沒有發生?第二個是更有效的方法嗎?更可讀?兩者相同?將函數的引用傳遞給C++中的指針,哪種方式更好?

1版

void ptrFunction(int& arg) 
{ 
    int* ptr = &arg; 
    std::cout<<"The pointer's value:" << *ptr << "\n"; 
} 

int main() 
{ 
    int x=5; 
    ptrFunction(x); 
    return 0; 
} 

2版

void CallViaPointers(int *arg) 
{ 
    int *ptr = *arg; 
    std::cout << "The pointer's value: " << *ptr; 
} 

int main() 
{ 
    int x = 100; 
    CallViaPointers(&x); 
    return 0; 
} 
+0

等等...這兩個等價物嗎? – 2011-02-09 02:52:53

+1

@muntoo:不,版本1中x = 5,版本2中x = 100) – Oystein 2011-02-09 02:57:23

+0

@Øystein哈哈。 :)無視這一點,版本1應打印5,但我不知道版本2. – 2011-02-09 03:23:01

回答

4

在效率方面,兩者幾乎肯定會向下編譯到幕後的相同的代碼,作爲參考通常實現爲自動解除引用的指針。從這個角度來看,這兩種解決方案是等價的。

至於是否通過指針或通過引用傳遞,這實際上是一個判斷電話,取決於情況。如果你想要做的只是打印一個指向整數的指針(就像你在這裏做的那樣),那麼通過指針就會更有意義,因爲它更明確地與你正在嘗試做什麼對齊。一般來說,編寫函數以便該參數是您想要的內部類型。如果你需要一個指針 - 或者因爲你正在構建一個鏈接結構,或者因爲你正在做某種內存分配 - 那麼接受一個指針。如果你正在處理多態類,那麼傳統上你會接受你的參數,而不是通過引用,儘管兩者都工作。如果您正在使用堆棧分配的對象來嘗試修改它,那麼引用可能會更清晰一些。而且,如果您處於其中一種情況,其中您必須使用引用(例如,作爲重載運算符,複製構造函數或賦值運算符的參數),那麼當然要使用引用。可讀性現在真的被低估了,但努力獲得乾淨,可讀,直觀的代碼是絕對值得的。

1

表現明智,當然它完全取決於實施。通常,它們將編譯成相同的機器碼。這絕對是那些你不應該考慮優化的情況之一,除非你必須這樣做。在大多數代碼中可讀性更重要。

至於可讀性,我傾向於更喜歡版本2,因爲我希望我的函數的用戶知道我要(或能夠)修改他放在那裏的任何東西,但是這個規則也有例外(例如捕捉異常或操作員重載時)。

1
int *ptr = *arg; 

應該是:

int *ptr = arg; 

我找到參考參數比指針參數更可讀的時候,目前還不清楚該參數將作爲一個指針其他地方。這通常是這種情況,並且參數的使用通常是封裝的,因此調用者不關心實現細節。然而,你可能不得不遵循一個現有的接口,並且可能使用指針作爲迭代器 - 然後你「按值傳遞一個迭代器」(傳遞一個迭代器的常用方式),而不是「傳遞一個指向對象的指針「,即使該迭代器實際上是一個原始指針類型。 (其他類型的現有接口是可能的。)

除了以上所述,個人偏好和允許空指針的一個(不能有空引用),它們在各方面都是相同的。

1

我想說這取決於功能。 現在您的函數名稱與它所做的不匹配。如果確實如此,它會被命名爲 print_pointer,並且很明顯它應該直接採用指針。 (我讀錯的問題,但是,是的,它仍然取決於你的函數做什麼。)

比方說,你有一個打印指針,就像一個功能:

void print_pointer(void* ptr) 
{ 
    std::cout << ptr << std::endl; 
} 

它不會使感覺這個函數被寫入引用,然後得到它的地址,因爲你不需要一個對象,你需要一個指向對象的指針,並且null在這個上下文中是有效的。

但是,如果您需要一個對象,就像您的代碼一樣,您應該參考一下,因爲指向該對象是一個實現細節;該界面帶有參考,清楚地表明您需要一個對象來參考。

現在看來,版本2是中斷,因爲傳遞null會使程序崩潰,但null是有效的指針值。如果不是這種情況,請不要通知您需要指針值。爲了解決這個問題,請檢查null並做一些清晰的記錄,就像沒有任何東西或拋出異常。但最好是將參數更改爲參考,因爲您將這些問題留給調用者,而且您的功能無論如何都能正常工作。如果有人有一個指向對象的指針,他們可以負責安全地將引用合法對象傳遞給你的函數,換句話說,使用引用是自我記錄:「null在這裏是無效的「)。

表現無關緊要。

1

它們是等價的,可以通過編譯和檢查反彙編進行驗證 - 除了符號名稱之外,它是相同的。

至於風格,它主要是個人偏好,但是有一種使用指針作爲out-parameters的常見模式。這是因爲當你參考時,你所調用的函數是否要修改它並不清楚。 「有效的C++」使用const引用來表示in-parameters和非const指針來表示out-parameters。我覺得這是一個很好的方式來說明合同是什麼。

相關問題