簡體   English   中英

通過引用傳遞c ++

[英]pass by reference c++

我的c ++老師告訴我,只有在我不打算更改函數內部數組的任何內容時才應該使用引用調用。 我有一些非常大的載體,我在我的程序中傳遞。 所有向量都將在函數內修改。 我的矩陣大小約為[256*256][256][50] ......

有沒有特別的理由不在這里使用call-by引用?

通過引用AFAIK調用應該更快,消耗更少的內存?

除了關於何時以及如何通過非原始類型的const引用傳遞的所有常見討論,這里的數組非常特殊。

由於與C的向后兼容性,並且由於您的特定問題:數組可能很大,因此數組永遠不會在C或C ++中通過值傳遞。 數組會衰變為指向第一個元素的指針,所以當你寫:

void foo( type array[100] );

編譯器實際上正在處理:

void foo( type *array );

無論數組的大小是多少(兩個常見的陷阱:相信該arrayfoo的數組,並且相信它將保證在其上有100個元素。

現在,在C ++中,您實際上可以通過引用傳遞數組,但引用必須是數組的具體類型,包括大小:

void foo_array( type (&array)[100] );

有趣的語法有告訴該函數將帶類型的准確100元件陣列的編譯器type 優點是編譯器可以為您執行大小檢查:

// assuming 'type' is defined
int main() {
   type array0[99];
   type array1[100];

   foo( array0 );     // compiles, but if size=100 is assumed it will probably break
                      // equivalent to: foo( &array0[0] )
   // foo2( array0 ); // will not compile, size is not 100
   foo2( array1 );    // compiles, size is guaranteed to be 100
}

現在,問題在於您的函數僅適用於包含100個元素的數組,在某些情況下,您可能希望以不同的數組大小執行相同的操作。 這兩個解決方案是:將函數模板化為數組的大小,這將為每個使用的大小提供一個大小安全的實現 - 更大的編譯時間和二進制大小,模板被編譯為每個不同的大小 - 或者使用傳遞 - 按值語法,這將使數組衰減 - 大小不安全,必須作為額外參數,較短的編譯時間和二進制大小傳遞。 第三種選擇是結合兩者:

void foo( type *array, int size );
template <size_t N>
void foo( type (&array)[N] ) {
   foo( array, N );
}

在這種情況下,雖然每個大小都有一個模板化的foo ,但編譯器很可能內聯調用,生成的代碼將等同於提供數組和大小的調用者。 不需要額外的計算和真實陣列的類型安全性。

現在,傳遞引用很少與數組一起使用。

我的c ++老師告訴我,只有在我不打算更改函數內部數組的任何內容時才應該使用引用調用。

當您不更改函數內部的內容更改內容並希望將更改反映到原始數組不關心要在原始數組中反映的更改時,應該使用它。

如果您希望函數更改原始數組(您需要在調用后保留原始值)並且被調用函數更改傳遞的參數的值,則不應使用它。

你的老師錯了。 如果需要修改數組,可以通過引用傳遞。 如果您不想修改某些內容,請通過const引用傳遞。

為防止意外更改,請使用pass-by-const-reference; 這樣,默認情況下*,傳入的數組不能被被調用的函數改變。

*可以用const_cast覆蓋。

您可以通過以下方式傳遞參考:

  1. 你不會修改傳遞的對象
  2. 你想修改對象,不想保持舊對象不變

當您通過引用傳遞某些內容時,只有指針被傳遞給函數。 如果你傳遞整個對象然后你需要復制它,所以它將消耗更多的CPU和內存。

等一下......我很害怕人們如何回答這個問題。 據我記得,數組總是通過引用傳遞。

void function(int array[])
{
    std::cout << array[0] << '\n';
}

// somewhere else..
int array[2] = { 1, 2 };
function(array); // No copy happens here; it is passed by reference

此外,您不能說數組參數是顯式引用,因為這將是創建引用數組的語法(不允許的事情)。

void function(int &array[]) // error here
{ /* ... */ }

所以你是什么意思?

此外,許多人說如果你修改函數內部數組的內容,你應該只這樣做。 然后,如何引用const?

void function(const int arr[])
{
    std::cout << arr[0] << '\n';
}

- 編輯

有人請指出如何在C ++中通過引用傳遞數組?

- 編輯

哦,所以你在談論矢量。 好的,那么經驗法則是:

  • 僅在您想要修改向量的內容時才通過引用傳遞。
  • 盡可能通過引用傳遞給const。
  • 僅當有問題的對象真的非常小時(例如,包含整數的結構),或者當它有意義時(不能想到我的頭腦中的情況),才傳遞值。

我錯過了什么?

- 編輯

  • 在普通C數組的情況下,當你想確保數組具有給定的確定大小時,最好通過引用傳遞它們(比如在void function(int (&array)[100]) )。

謝謝,運動員。

一般來說,對象應始終通過引用傳遞。 否則,將生成對象的副本,如果對象非常大,則會影響性能。

現在,如果您調用的方法或函數不修改對象,最好按如下方式聲明函數:

void some_function(const some_object& o);

如果您嘗試修改函數體內的對象狀態,則會生成編譯錯誤。

還應注意,數組總是通過引用傳遞。

通常,在入門課程中,他們會告訴您,所以您不會意外地更改您不想要的內容。

就像你通過引用傳入userName,並意外地將其更改為mrsbuxley,這可能會導致錯誤,或者至少在以后會引起混淆。

我沒有看到你不能通過引用傳遞的任何理由。 或者你可以傳遞指針,但我認為通過引用傳遞有時更好,因為它避免了空指針異常。

如果你的老師已經建議將其作為某種慣例,那么如果它有意義,請隨意打破它。 您始終可以在功能上方的注釋中記錄此內容。

我們的家庭風格是永遠不會通過值傳遞對象,但始終傳遞引用或const引用。 我們不僅擁有可以包含100個MB數據的數據結構,並且按值傳遞將是應用程序殺手,而且如果我們按值傳遞3D點和向量,我們的應用程序將停止運行。

通過引用傳遞對象總是一個很好的選擇,但我們需要小心,首先我們必須決定我們的功能的目的/目的是什么?

你必須在這里做出選擇,我們是否只會讀取對象的數據或修改它。

假設你有一個像這樣的界面

void increament_value(int& a);

所以在這里你可以修改我們傳遞的對象的值,但是當你傳遞敏感數據時,這可能是一個災難,你可能會丟失原始數據並且無法恢復它,對吧?

所以c ++提供了一種功能,可以不改變你傳遞給函數的引用的對象的值,並且傳遞對象的const引用總是一個很好的選擇,例如,

double get_discounted_amount(const double &amount,double discount){
    return (amount*discount/100);
}

這可以保證您對象的實際值不會發生變化,但是這又取決於您的界面的用途,無論您是想更改它還是僅使用(讀取)它

暫無
暫無

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

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