前兩天摸魚聊天的時候遇到一個問題,一個鏈表的函數中,有一個參數顯得很奇怪
(大概是一個樣子的)ListNode<T>*& l
這個參數l除了用了一個*之外還用了一個&,直覺上*&是一個解引用一個取地址,似乎應該相互抵消,但是那樣這樣的代碼就毫無意義,既然沒有意義作者也沒有必要這樣去寫,因此這肯定是一個特殊的用法,事實上,我之前在stl源碼剖析中遇到過這個,但是之前我將它這樣解釋:因為*的運算優先級比較低(在我的印象中,*一直很低,但是和&誰先我並不清楚,導致了之后的一個錯誤理解),所以我認為是這樣解釋的:ListNode<T>* (&L),那么就是首先提取L的地址,傳入的就是一個ListNode對象的地址,然后再解引用,讓L成為一個單純的對象,這樣可以省去一個構造函數和一個析構函數成本。然而當有人提到這個問題的時候,我卻發現這個解釋有點站不住腳,因為我是憑印象認為*解引用的優先級比較低,然而那是針對加減之類的運算符而言的,與&的關系我並不明確;而且傳入一個地址,L卻這樣神奇的轉化成了一個對象,有點太過玄幻。
於是我百度了一下,發現應該是這樣解釋的:(ListNode<T>*)& l,即將ListNode<T>*整個的作為一個類型,並將l設置成這樣的一個類型的引用。
那么這個l的實際意義其實是一個指針的引用,這個指針的類型是ListNode<T>*
需要注意的是,它與ListNode<T>* l的區別:
乍看之下對一個指針用引用有點奇特,但是根據指針也只是一個變量來分析,可以想到,傳遞一個指針的引用,同時就可以修改這個指針本身。
接下來就是結論:
ListNode<T>* l,這個l可以修改l所指的鏈表節點對象,然而這個函數不能修改l指針本身,也就是修改l所指的對象並不能起作用(如果作為返回值就另說,不在這篇博客的討論范圍內)
ListNode<T>*& l 這個l不僅可以修改l所指的鏈表節點對象,而且這個函數可以修改l指針本身,也就可以修改l所指的對象。
於是,這個故事告訴我們不要憑感覺做事(逃)