簡體   English   中英

在C ++中,傳遞指針優先於傳遞引用時是什么?

[英]When pass-by-pointer is preferred to pass-by-reference in C++?

我可以想象一種情況,其中輸入參數可以為NULL,因此首選通過指針而不是通過引用?

有人可以增加更多案件嗎?

在實際上要修改要傳遞的對象的情況下,有些對象更喜歡傳遞指針。 當通過引用傳遞對象時,它們使用pass-by-const-reference來避免對象的復制,但不會在函數中更改。

在說明中,采用以下功能:

int foo(int x);
int foo1(int &x);
int foo2(int *x);

現在在代碼中,執行以下操作:

int testInt = 0;

foo(testInt);   // can't modify testInt
foo1(testInt);  // can modify testInt

foo2(&testInt); // can modify testInt

在調用foo vs foo1時,從調用者的角度(或程序員閱讀代碼)來看,該函數可以修改testInt而不必查看該函數的簽名,這並不明顯。 查看foo2,讀者可以很容易地看到該函數實際上可以修改testInt的值,因為該函數正在接收參數的地址。 請注意,這不能保證對象實際上已被修改,但這在使用引用和指針方面保持一致是有幫助的。 通常,如果要始終遵循此准則,則在避免復制時應始終傳遞const引用,而在希望能夠修改對象時應始終通過指針傳遞。

C ++ FAQ對於以下問題有很好的答案:

盡可能使用引用,而必須使用指針。

每當不需要“重新設置”時,通常比引用更喜歡引用。 這通常意味着引用在類的公共接口中最有用。 引用通常顯示在對象的外觀上,而指針則顯示在對象的外觀上。

上面的例外是函數的參數或返回值需要“前哨”引用,即不引用對象的引用。 通常最好通過返回/獲取指針,並賦予NULL指針特殊的意義來完成此操作(引用應始終是別名對象,而不是取消引用的NULL指針)。

注意:舊的C語言程序員有時不喜歡引用,因為它們提供的引用語義在調用者的代碼中並未明確。 然而,經過一些C ++經驗,人們很快意識到這是一種信息隱藏的形式,它是一種資產而不是一種負債。 例如,程序員應該用問題的語言而不是機器的語言來編寫代碼。

在現實世界編程中,您會遇到很多情況,其中參數不存在或無效,並且這可能取決於代碼的運行時語義。 在這種情況下,可以使用NULL(0)表示此狀態。 除此之外,

  • 可以將指針重新分配給新狀態。 引用不能。 在某些情況下這是理想的。
  • 指針有助於轉移所有者的語義。 如果參數狀態用於在單獨的線程中執行,並且通常在線程退出后才進行輪詢,這在多線程環境中尤其有用。

盡管如果花了足夠的時間正確地設計代碼,則可以避免這些情況。 實際上,不可能每次都這樣。

除了有關所有權語義(尤其是工廠功能)的其他答案之外。

盡管不是技術原因,但常見的樣式指南要求是任何可以修改的參數都應通過指針傳遞。 這使得在呼叫站點可以修改對象變得顯而易見。

void Operate(const int &input_arg, int *output_arg) {
  *output_arg = input_arg + 1;
}

int main() {
  int input_arg = 5;
  int output_arg;
  Foo(input_arg, &output_arg);  // Passing address, will be modified!
}

規則一:如果NULL是函數上下文中函數參數的有效值,則將其作為指針傳遞,否則將其作為引用傳遞。

基本原理,如果它不能(不應!)永遠為NULL,則不要讓自己陷入檢查NULL的麻煩之中,否則就不要為NULL冒問題。

這不是專門傳遞參數,但確實會影響傳遞參數。

您可以具有指針的容器/集合,但不能具有引用的容器/集合。 盡管引用是多態的,但只有指針支持容器使用必不可少的“更新”操作(特別是因為您還無法大規模初始化引用,所以不確定C ++ 0x聚合初始化器是否會對此進行更改)。

因此,如果您有一個充滿指針的容器,那么通常最終將使用接受指針而不是引用的函數來對其進行管理。

處理原始內存時(例如,如果創建自己的內存池),則需要使用指針。 但是您是對的,在普通代碼中,指針的唯一用途是可選參數。

在C ++中,大多數情況下幾乎不需要傳遞指針。 您應該首先考慮替代方案:模板,(常量)引用,容器,字符串和智能指針。 就是說,如果您必須支持舊代碼,則需要使用指針。 如果您的編譯器是簡約的(例如嵌入式系統),則需要指針。 如果您需要使用C庫(正在使用的特定驅動程序的某種系統庫?),則需要使用指針。 如果要處理非常特殊的內存偏移,則需要指針。

在C語言中,指針是一流的公民,它們太基礎了,無法考慮消除它們。

任何時候傳遞函數指針。 或者,如果您有“重置”方法,請使用auto_ptr。

當您需要操縱(例如調整大小,重新分配等)函數內部指針所指向的地址時,則需要一個指針。

例如:


void f( int* p )
{
    // ..

    delete []p;
    p = new int[ size ];

    //...
}

與引用不同,指針的值可以更改和操縱。

Google對此似乎有強烈的意見,我傾向於同意:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments

可以想象,可以編寫一個函數來對內存執行某些操作,例如重新分配它以使其更大(返回新指針)。

如果需要傳遞對象數組,則需要通過指針傳遞。 數組並不總是存儲在std::vector<>

除此之外,通過指針傳遞允許空值和通過引用傳遞沒有,所以我用這樣的區分是很像一個合同NULLNOT NULL在SQL列,而松散像“函數返回booltrue =成功和false =失敗,而函數返回int :返回值是結果代碼,其中0 =成功,其他則是失敗”。

暫無
暫無

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

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