簡體   English   中英

指針與參考

[英]Pointer vs. Reference

在給函數提供原始變量時,最好的做法是:

unsigned long x = 4;

void func1(unsigned long& val) {
     val = 5;            
}
func1(x);

要么:

void func2(unsigned long* val) {
     *val = 5;
}
func2(&x);

IOW:有沒有理由選擇一個而不是另一個?

我的經驗法則是:

如果你想用它們做指針運算(例如遞增指針地址以逐步遍歷數組)或者你必須傳遞一個NULL指針,請使用指針。

否則使用參考。

我真的認為你將從建立以下函數調用編碼指南中受益:

  1. 正如其他所有地方,永遠是const -correct。

    • 注意:除其他外,這意味着只有out-values(參見第3項)和value傳遞的值(參見第4項)可能缺少const說明符。
  2. 如果值0 / NULL是當前上下文中的有效輸入,則僅通過指針傳遞值。

    • 理由1:作為調用者 ,您會看到無論您傳入的是什么,都必須處於可用狀態。

    • 理由2:由於 ,你知道,無論發生什么事在處於可用狀態。 因此,不需要對該值進行NULL檢查或錯誤處理。

    • 基本原理3:基礎知識1和2將被編譯器強制執行 如果可以的話,總是在編譯時捕獲錯誤。

  3. 如果函數參數是out-value,則通過引用傳遞它。

    • 理由:我們不想打破第2項......
  4. 只有當值是POD( 普通舊數據結構 )或足夠小(內存方式)或以其他方式足夠便宜(按時間)復制時,選擇“按值傳遞”而不是“傳遞const引用”。

    • 理由:避免不必要的副本。
    • 注意: 小到足夠 便宜並不是絕對可衡量的。

這最終成為主觀的。 到目前為止的討論很有用,但我認為沒有正確或果斷的答案。 很多將取決於風格指南和您當時的需求。

雖然使用指針有一些不同的功能(無論是否可以為NULL),但輸出參數的最大實際差異純粹是語法。 例如,谷歌的C ++風格指南( https://google.github.io/styleguide/cppguide.html#Reference_Arguments )只強制指針輸出參數,並且只允許引用為const。 推理是可讀性:具有值語法的東西不應該具有指針語義。 我並不是說這必然是對或錯,但我認為這里的重點是風格,而不是正確性。

如果要修改變量的值,則應傳遞指針。 即使技術上傳遞引用或指針是相同的,在您的用例中傳遞指針更具可讀性,因為它“通告”該值將由函數更改的事實。

如果您有一個參數,您可能需要指示缺少值,通常的做法是使參數成為指針值並傳入NULL。

在大多數情況下(從安全角度來看)更好的解決方案是使用boost :: optional 這允許您通過引用傳遞可選值,也可以作為返回值。

// Sample method using optional as input parameter
void PrintOptional(const boost::optional<std::string>& optional_str)
{
    if (optional_str)
    {
       cout << *optional_str << std::endl;
    }
    else
    {
       cout << "(no string)" << std::endl;
    }
}

// Sample method using optional as return value
boost::optional<int> ReturnOptional(bool return_nothing)
{
    if (return_nothing)
    {
       return boost::optional<int>();
    }

    return boost::optional<int>(42);
}

指針

  • 指針是保存內存地址的變量。
  • 指針聲明由基類型,*和變量名組成。
  • 指針可以指向生命周期中的任意數量的變量
  • 當前未指向有效內存位置的指針的值為null(為零)

     BaseType* ptrBaseType; BaseType objBaseType; ptrBaseType = &objBaseType; 
  • &是一個一元運算符,返回其操作數的內存地址。

  • 解除引用運算符(*)用於訪問存儲在指針指向的變量中的值。

      int nVar = 7; int* ptrVar = &nVar; int nVar2 = *ptrVar; 

參考

  • 引用(&)類似於現有變量的別名。

  • 引用(&)就像一個自動解除引用的常量指針。

  • 它通常用於函數參數列表和函數返回值。

  • 必須在創建引用時初始化引用。

  • 將引用初始化為對象后,無法將其更改為引用另一個對象。

  • 您不能有NULL引用。

  • const引用可以引用const int。 它由一個帶有const值的臨時變量完成

     int i = 3; //integer declaration int * pi = &i; //pi points to the integer i int& ri = i; //ri is refers to integer i – creation of reference and initialization 

在此輸入圖像描述

在此輸入圖像描述

盡可能使用引用,必要時使用指針。 C ++ FAQ:“我應該何時使用引用,何時應該使用指針?”

引用是隱式指針。 基本上,您可以更改引用指向的值,但不能將引用更改為指向其他內容。 所以我的2美分是,如果您只想更改參數的值,則將其作為參考傳遞,但如果您需要將參數更改為指向其他對象,請使用指針傳遞它。

考慮一下C#的out關鍵字。 編譯器要求方法的調用者將out關鍵字應用於任何out args,即使它已經知道它們是否存在。 這旨在增強可讀性。 雖然使用現代IDE,我傾向於認為這是語法(或語義)突出顯示的工作。

除非您有理由更改/保留您傳入的內容,否則請通過const引用。

在大多數情況下,這將是最有效的方法。

確保在每個不希望更改的參數上使用const,因為這不僅可以保護您不會在函數中做一些愚蠢的事情,而且可以很好地向其他用戶指示函數對傳入的值的作用。 這包括當你只想改變指向的時候制作指針const ...

指針:

  • 可以分配nullptr (或NULL )。
  • 在調用站點,如果您的類型不是指針本身,則必須使用& ,明確表示您正在修改對象。
  • 指針可以反彈。

參考文獻:

  • 不能為空。
  • 一旦綁定,就無法改變。
  • 呼叫者不需要明確使用& 這有時被認為是錯誤的,因為您必須轉到函數的實現以查看您的參數是否被修改。

引用類似於指針,除了您不需要使用前綴*來訪問引用引用的值。 此外,不能在初始化之后引用不同的對象。

引用對於指定函數參數特別有用。

有關更多信息,請參閱“Bjarne Stroustrup”(2014)第11-12頁的“C ++之旅”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM