2014-03-27 52 views
1

參考哪一個更好:通過引用傳遞使用void increment(int& x)或使用void increment(int* x)通過指針通行證?通行證使用指針和間接引用指針

  1. void increment(int& x) 
    { 
        x=x+1; 
    } 
    int main() 
    { 
        int n= 2; 
        increment(n); 
        cout << "Value of n is " << n << '\n'; 
        return 0; 
    } 
    

  2. void increment(int* x) 
    { 
        *x=*x+1; 
    } 
    int main() 
    { 
        int n= 2; 
        increment(&n); 
        cout << "Value of n is " << n << '\n'; 
        return 0; 
    } 
    
+2

什麼是你的 「更好」 的標準是什麼? –

+0

相關:http://programmers.stackexchange.com/questions/214997/reference-vs-dereference-pointers-in-arguments-c-c –

回答

3

都不是更好的。使用指針的好處在於它在調用代碼中明確指出參數是通過指針傳遞的,因爲參數前面有&。使用引用的優點在於它在調用函數代碼中更自然,沒有全部的解除引用。內部通常以相同的方式實施,所以應該沒有速度優勢。

1

不知道你認爲「更好」是什麼意思,我只能說他們是不同的。

傳球

優點參考:

  1. 按引用傳遞將阻止你通過nullptr,將使其更難以通過無效值。

就性能而言,您不會看到太多差異。通過指針傳遞的

優點:

  1. 通過引用傳遞不兼容C,所以,如果你暴露你期望能夠在C調用的函數,你需要使它傳遞一個指針。

  2. 傳遞指針可以讓你通過nullptr/NULL。雖然將此列爲優點可能與列出無法將其作爲參考的好處相矛盾,但這取決於您如何使用您的功能。如果你想讓能夠指定參數沒有值(並且不想包含boost::optional或者滾動你自己的),那麼指針是一種習慣的方式。

在這種特殊情況下,我寧願通過引用來傳遞,因爲沒有理由在沒有有效值的情況下調用該函數。

0

我的經驗個人統治:

  • 使用指針(輸入/)輸出參數,所以它是立即清除該功能將改變正常參數
變量
  • 使用引用

    所以在你的情況下,功能increment()明顯改變了傳入的變量,我會使用一個指針。如果您使用引用,讀取代碼的人將不得不跳轉到函數的聲明以瞭解函數的副作用。

  • -2

    對於一個面向外部的組件(即編寫一個庫時第三方會消耗),我會帶一個指針,它讓用戶知道你要修改他們傳入的內容。這是以指針解引用爲代價的它具有非常小的性能成本 - 因爲在使用它之前您需要檢查指針不是NULL

    對於不打算公開的內部函數,通過引用是優選的,因爲它更容易編寫,並且(同樣,只是非常輕微)更高性能。

    鏗鏘沒有的優化:

    00000000004004c0 <_Z10doThingRefRi>: 
        4004c0:  48 89 7c 24 f8   mov %rdi,-0x8(%rsp) 
        4004c5:  48 8b 7c 24 f8   mov -0x8(%rsp),%rdi 
        4004ca:  8b 07     mov (%rdi),%eax 
        4004cc:  05 01 00 00 00   add $0x1,%eax 
        4004d1:  89 07     mov %eax,(%rdi) 
        4004d3:  c3      retq 
        4004d4:  66 66 66 2e 0f 1f 84 data32 data32 nopw %cs:0x0(%rax,%rax,1) 
        4004db:  00 00 00 00 00 
    
    00000000004004e0 <_Z10doThingPtrPi>: 
        4004e0:  48 89 7c 24 f8   mov %rdi,-0x8(%rsp) 
        4004e5:  48 81 7c 24 f8 00 00 cmpq $0x0,-0x8(%rsp) 
        4004ec:  00 00 
        4004ee:  0f 84 0f 00 00 00  je  400503 <_Z10doThingPtrPi+0x23> 
        4004f4:  48 8b 44 24 f8   mov -0x8(%rsp),%rax 
        4004f9:  8b 08     mov (%rax),%ecx 
        4004fb:  81 c1 01 00 00 00  add $0x1,%ecx 
        400501:  89 08     mov %ecx,(%rax) 
        400503:  c3      retq 
        400504:  66 66 66 2e 0f 1f 84 data32 data32 nopw %cs:0x0(%rax,%rax,1) 
        40050b:  00 00 00 00 00 
    

    鏗鏘和-O3

    00000000004004c0 <_Z10doThingRefRi>: 
        4004c0:  ff 07     incl (%rdi) 
        4004c2:  c3      retq 
        4004c3:  66 66 66 66 2e 0f 1f data32 data32 data32 nopw %cs:0x0(%rax,%rax,1) 
        4004ca:  84 00 00 00 00 00 
    
    00000000004004d0 <_Z10doThingPtrPi>: 
        4004d0:  48 85 ff    test %rdi,%rdi 
        4004d3:  74 02     je  4004d7 <_Z10doThingPtrPi+0x7> 
        4004d5:  ff 07     incl (%rdi) 
        4004d7:  c3      retq 
        4004d8:  0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 
        4004df:  00 
    
    +0

    「次要性能成本」?一個參考也必須被解除引用。事實上,大多數編譯器將在內部使用指針來實現引用。 –

    +0

    在引用引用之前,您不必檢查空值是否來自成本。我將用一些彙編編輯這個答案來指出這一點。 – Michael

    +0

    如果你看這裏:http://goo.gl/yGSy9s生成的彙編代碼在這兩種情況下是相同的。所以不,沒有性能差異。 –