2014-07-17 65 views
-5

我需要一次一個和所有的澄清值傳遞/指針/參考。通過數值/指針/參考說明

如果我有一個變量如

int SomeInt = 10; 

而且我想通過SomeInt時DoSomething的()我想SomeInt的價值,它像

void DoSomething(int Integer) 
{ 
    Integer = 1; 
} 

傳遞給函數在我目前的情況下根據我們在DoSomething()裏面對它做的任何事情來更新,以及在內存和性能方面最有效率,所以我不會複製變量?這是說以下哪個原型可以完成這項任務?

void DoSomething(int* Integer); 
void DoSomething(int& Integer); 

我該如何將變量傳遞給函數?前兩個原型有什麼區別?

最後,如果使用函數的類

class SomeClass 
{ 
    int MyInteger; 

public: 
    void ChangeValue(int& NewValue) 
    { 
     MyInteger = NewValue; 
    } 
}; 

內如果我整數關口進入ChangeValue,在整數i中獲取的刪除通過將意味着,當我嘗試使用MyInteger從類它將內不再可用?

謝謝大家的時間,我知道這是一個基本的問題,但我繼續陷入困惑的解釋進一步。

+0

是,這些功能可能會完成任務。 –

+3

-1我會對一生中的一次澄清感興趣,人們如何打算學習像C++這樣複雜的編程語言,而不必查看基本的學習材料。 – Solkar

+0

您可能有興趣閱讀常見問題解答問題http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c – Cecilia

回答

4

功能,所有這三個工作:

  • 傳遞一個int變化返回類型int這樣你就可以返回新值,用法:x = f(x);

    • 當你計劃中設定的值而不需要讀取初始值,這是更好使用功能類似int DoSomething();所以調用者就可以說int x = f();,而不必在較早線創建x和疑惑/擔心它是否需要初始化爲調用之前任何事情。
  • 傳遞一個int&並將其設置的功能,使用內部:int x; x = ? /* if an input */; f(x);

  • 傳遞一個int*並設置指向的int在函數內部,用法:int x; x = ?; f(&x);

最高效的內存和性能,所以我不是抄襲周圍

變量3210

考慮到C++標準並沒有規定如何通過編譯器實現引用,所以試圖推斷它們的特性時有點懷疑 - 如果你關心的是將代碼編譯成彙編代碼或機器代碼並查看它是如何工作的在你的特定編譯器上(對於特定的編譯器命令行選項等)。如果您需要一個經驗法則,則假定引用與指針具有相同的性能特徵,除非分析或生成代碼檢查另有建議。

對於int你可以期望上面的第一個版本是沒​​有比指針版本的比較慢,並且可能會更快,因爲int參數可以從寄存器中傳遞和返回而沒有需要一個內存地址。

如果/當/當通過指針版本是內聯有更多的機會,有可能慢「需要一個內存地址,所以我們可以傳遞一個指針」 /「不得不取消引用指針訪問/更新值「的通用指針版本方面仍然可以優化掉了(如果你問的編譯器試試),留下兩個版本具有相同的性能....

,如果你需要問這樣一個問題這個我無法想象你寫的代碼,其中這些都是重要的優化選擇,所以更好的目標是做什麼給你的客戶端代碼最乾淨,最直觀,最強大的用法......現在 - 不管是x = f(x);(你可能會忘記領先的x =),或f(x)下,您可能沒有意識到x可以修改,或f(&x)(其中有些來電者可能會認爲他們可以通過nullptr是在自己的權利一個合理的問題,但是從你的性能問題分開。FWIW,C++ FAQ Lite建議引用這種情況的指針,但我個人拒絕它的推理和結論 - 這一切都歸結爲熟悉任何一種約定,以及您需要多長時間通過const指針值或指針值nullptr是一個有效的哨點,可能會與您的場景中所希望的您可能會修改我的含義混淆......這取決於您的編碼風格,您使用的庫,問題域等等。

+0

謝謝。我在應用程序的每一處傳遞了指針,但是我最近遇到了輕微的性能下降,並希望100%清除指針/引用,以及如何避免在函數調用過程中不惜一切代價複製變量。 – KKlouzal

+0

不客氣。當你傳遞緩慢複製的大對象時,通過指針或引用傳遞可能會很有用,但是如果給定'int'不大並且可能比指針小,那麼對'int'沒有幫助。不妨嘗試一下探查器(例如g ++/VC++包含內置探測器,ValGrind等) - 這可能會引發各種意想不到的事情,從而產生更大的差異。 –

0

您可以使用。函數調用的第一個原型是

DoSomething(&SomeInt); 

和第二架原型機

DoSomething(SomeInt); 
4

的你的例子都

void DoSomething(int* Integer); 
void DoSomething(int& Integer); 

能完成這個任務。在第一種情況 - 與指針 - 你需要調用函數DoSomething(&SomeInt);,在第二種情況下 - 參照 - 簡單,因爲DoSomething(SomeInt);

推薦的方法是,每當他們就能夠使用引用和指針,只有當他們是必要。

+0

好的非常感謝你,最後一件事可以請你請參閱問題中的類示例? – KKlouzal

+0

@KKlouzal「如果我將一個整數傳遞給ChangeValue,那麼當我在get中刪除的整數將意味着當我嘗試從類中使用MyInteger時,它將不再可用?」 - 你不能「刪除」一個整數。 MyInteger只是獲得了新的價值,但稍後可以完美使用。 –

0

如前所述,您可以同時使用兩者。

void DoSomething(int* Integer) 
{ 
    *Integer=0xDEADBEEF; 
} 
DoSomething(&myvariable); 

模式是,從調用中顯而易見,myvariable可能會發生變化。

void DoSomething(int& Integer) 
{ 
    Integer=0xDEADBEEF; 
} 
DoSomething(myvariable); 

模式的優點是,在DoSomething的代碼是有點清潔,DoSomething的具有較硬的時間來惹不好的方式來存儲和你可能會得到更好的代碼出來。缺點是從閱讀調用中可以看出,myvariable可能會發生變化。

+0

如果你關心'myvariable'被改變,那麼它應該已經是'const'。 –

+0

如果您遇到類似i = 0的情況, DoSomething的(I);我++;我不能成爲常客,你是否非常關心我是否改變。 –

+0

所以只是不要那樣做...你的代碼被破壞了。當'i'不是'const'時,你將'i'傳遞給你不想修改'i'的函數。非常差的設計。 –