2012-03-16 66 views
12

C++ FAQ說:在所有情況下,最喜歡C++引用指針嗎?

「使用的時候可以參考和指針,當你不得不這樣做。」

我覺得上面說,它不是那麼容易。已經很好地討論了引用通常對指針更好的原因。所以,我寧願談談特殊情況下的參考意義,但極不尋常的,只是覺得不舒服:

對我來說,最明顯的例子是他們就像一棵樹或linked- 通用數據結構使用名單。其接口可使用的引用和感覺更安全地肯定實現,但我還沒有看到一個單一的實現,將採取引用的優勢,例如:

Node *parent = n.parent(); // parent might be unset -> pointer 
Node &child = n.child(5); // child is always valid -> reference 

雖然似乎有吸引力,它會導致這樣的代碼:

if(parent == &child) ... // weird, unusual at least? 

我不知道,這算什麼代表純C++?

每一個我試圖盲目使用引用無論它是可能的時候,我遇到的各種類似不一致,結束了混合指針和各種醜陋的方式引用

總之,爲什麼運營商新沒有返回一個引用到一個新的實例,而不是一個指針? (在錯誤的情況下拋出):

Node &n = new Node; 
delete &n; 

這是一個荒謬的例子,但是,這不是什麼會是「純粹的C++」?

+6

你錯過了這一點。將報價想象爲「儘可能使用自動存儲,並在必要時動態存儲(新建)」。 – ildjarn 2012-03-16 22:06:08

+2

使用任何有意義的東西。通常,這意味着實現容器的指針,以及客戶端代碼中的引用。而且,沒有人能夠阻止任何人寫出荒謬的代碼,所以如果有人說'delete&x;',那麼你可以做的不多。你必須假設你的客戶*希望*編寫正確的程序。你只需要讓他們變得容易。 – 2012-03-16 22:07:09

+0

將對象傳遞給函數時,引用也是首選,因爲由於沒有調用複製構造函數而更快。 – chris 2012-03-16 22:07:28

回答

-5

「new」運算符分配內存(就像C中的malloc一樣)。由於C++沒有實現垃圾收集器(如Java或C#),因此可能會導致內存不足。因此,當new分配內存失敗時返回NULL值。這樣你可以測試分配是否成功。

由於可能由於缺少內存而導致分配NULL值,因此不能使用新運算符的引用。

+5

*由於C++沒有實現(如Java或C#)一個垃圾收集器就可以運行內存不足* [難不成Java可以沒有用完的內存?](http://www.google.com.au/webhp ?的SourceID =鉻瞬間&即= UTF-8&離子= 1#HL = EN&sugexp = frgbld&gs_nf = 1&CP = 14&gs_id = 2&XHR = T&q = java.lang.outofmemoryerror&PF = p輸出=搜索和sclient = PSY-AB和OQ = java.lang.outo&水溶液= 0&AQI = G4&AQL =&gs_sm =&gs_upl =&gs_l =&PBX = 1&BAV = on.2,or.r_gc.r_pw.r_qf。,cf.osb&FP = 9ac572733e1be876&BIW = 1920&波黑= 979&離子= 1) – 2012-03-16 22:26:11

+4

'new'不返回NULL,則拋出異常。 – 2012-03-16 22:27:26

+4

'new'不返回NULL,它拋出'std :: bad_alloc'。爲了讓'new'在分配失敗時返回NULL,你需要用'std :: nothrow'參數來調用它。 – Praetorian 2012-03-16 22:27:48

6

我認爲通用數據結構屬於「必須使用時使用指針」子句。也就是說,由於引用是常量(即它們總是指向同一個對象),在鏈表或樹節點結構中使用引用意味着不能插入新節點或從數據結構中刪除舊節點 - 通常會導致目的。

正如有人在評論中所說,我認爲這個建議確實適用於函數參數。傳遞引用而不是指針避免了必須爲每個函數添加空指針處理邏輯,這爲代碼大小和清晰度帶來了許多好處。

+0

對於樹節點,您可以在技術上使用接口中的引用,並通過操作使用指針的內部表示來插入和刪除節點。這將有點奇怪,但仍然有可能。否則,我同意,在函數參數的背景下,引用是最有意義的。 – FipS 2012-03-16 22:41:58

+1

有引用數據成員有這種習慣,導致任何類型的問題需要用價值語義來處理,例如,複製。 – 2012-03-16 22:45:15

+0

是的,並且當您使用指針數據成員而不是引用來允許複製語義時。問題在於,即使在接口中使用指針,或者將指針暴露爲引用。我個人堅持使用指針,但我懷疑這個建議是在這種情況下使用引用。 – FipS 2012-03-16 23:23:38

10

引用不能被修改爲在初始化後引用不同的對象。但是可以修改指針以在運行時引用不同的對象。

拇指

每當你想一個變量來在其生命的時間指向不同的對象,使用指針的一般規則。

如果你只是想用一個變量作爲另一個變量使用參考的別名。

作爲參數

我們有時傳遞參數作爲參考(常量/非const)。這有助於在每次調用函數時避免複製整個對象。因此,當傳遞大尺寸的對象時,這會很有意義。

如果函數需要接收一些參數比可以選擇爲空,你可以使用一個指針。但是,再次,您可以爲任何類定義靜態空對象,並且可以使用它。

作爲返回值

每當我們重載運算符,如[]或< <,我們將返回引用。這是因爲,如果我說vec [0] = 10,它實際上應該將值10分配給vec中的位置0。在這裏,我不能使用指針的原因很明顯。 * vec [0] = 10不會很好看。另外,你應該保證,當你返回一個引用時,它總是指向一個對象(它不應該爲空)。

同樣,當函數可以返回NULL值,使用指針,否則你可能需要聲明爲類的靜態空對象。

作爲數據成員

參考文獻應在構造函數初始化。因此,一旦對象被構建,它們就不能被改變。

因此,如果您需要在類的生命週期中指向不同對象的變量,指針將是一個不錯的選擇。

+1

+1歡迎來到SO並祝賀相當不錯的首次亮相;) – 2012-03-16 22:50:44

+0

謝謝Christian。 – 2012-03-23 19:05:49

1

如果熟悉NULL和NOT NULL列在關係數據庫中,或具有強制性的,並且在XSD可選元素之間的差,則可以從這樣的域繪製有用平行於指導你。

參考會站在爲固定變量,獨立的和不能爲空。指向那些你真正需要的人有時會傳遞「沒有價值」,或者你明確需要執行指針運算(例如使用數組)。這絕不是唯一的區別,但大多數不同的語法都是從那裏開始的。

回顧:reference = NOT NULL和只讀。指針=靈活,有點危險。

相關問題