標籤:

C++ 中為什麼要有. -> ::這幾種成員訪問操作符?

如果統一用 . 的話,編譯器能不能根據上下文判斷出來?


C++ 的設計原則之一是要和 C 兼容,而 C 就有 . 和 - &> 。所以這是一個 C 的問題。

C++ 允許 overload - &> 而不允許 overload . 是一個順勢的便宜之計(因為兩個都不允許有違 C++ 讓 custom type 和 built-in type 盡量地位相當的原則,而兩個都允許又太混亂。此原因在《 The Design and Evolution of C++ 》中有詳細介紹)。這個不是存在兩個操作符的原因。

而 C 語言的設計,在高層的 language construction 方面已經大刀闊斧減到完美的地步。所以在細節設計方面就不會有什麼矛盾,因此 C 的細節設計可以說很隨意。比如省略返回值的類型不是 void 而是 int 。比如 enforced cast 的括弧在 type 上而不在 operand expression 上。所以在同時有 . 和 - &> 這個問題上不必過於糾結。


:: 是消除歧義用的。假設產生歧義,必須明確指定你要調用的函數是哪一個,你要訪問的成員是哪一個的時候,就要用這個。比如說你在某個類的成員函數中調用另一個和全局函數同名的成員函數(例如你的類定義一個成員函數,MessageBox,然後在另一個成員函數調用全局的 MessageBox 時,不寫 :: 那就會默認是調用這個重名的成員函數)。以及,你有兩個基類,這兩個基類有同名的成員屬性。

-&> 和 「點」,作用都是基址+偏移,主要差別在於顯式的指明左側的性質,是一個指針,還是一個對象的名稱(符號)。這個對程序員閱讀理解代碼還比較有用。我覺得這種區分的非常明確的做法,並不是一個必須的規定,只是已經形成這樣的傳統了。


::存在的原因是因為C++有多繼承,所以它需要用這個符號指定不同繼承路徑下的同名函數。同時C++有不屬於任何類的全局函數,與方法重名時需要用::指定。Java應該是沒有多繼承的,也沒有類外的函數的。

另外兩個是為了兼容C。


猜測應該是有些歷史的原因在裡面。至少在Java裡面,只有"."分隔符,雖然Java沒有指針,但是區別引用和指針對編譯器來說應該不是問題。


首先,C是區分.和-&>的,所以C++就需要區分.和-&>。
那麼,C為什麼要區分.和-&>呢?其實沒必要區分,其實對於C來說,都用.完全可以。-&>本身就是語法糖,既然已經糖了,索性更進一步直接把指針的.理解成解引用完全說得通。
所以,C區分.和-&>純粹是為了好玩、好看,隨便那麼一抽風,就區分了。
而C++要求自己兼容C,所以當然也就區分.和-&>。至於說區分.和-&>可以支持智能指針,這只是附帶的好處,而不是設計的原因。
至於說::,反正.和-&>問題上已經放棄治療了,堅持這種節操還有什麼意義。
你看沒有歷史負擔的C#,不就不區分::和.了嗎?再比如同樣有指針概念的objective c,不就不區分.和-&>嗎?


我感覺用不同的符號有這個作用:
1、對於程序員來說,知道自己用的是對象,還是指針,還是名字空間,特別是需要知道是指針,因為可能還要釋放動態內存,這樣提高程序的可讀性。
2、對於編譯器構造者來說,構造符號表和類型檢查的時候,這三者的處理方式,和檢查方式就不一樣了,更有必要分開操作了


-&>和.用於對象成員,兩者意義完全不同,p-&>a等價於(*p).a;::用於類成員


如果統一用".",不能通過上下文判斷。
舉個栗子:

有個智能指針,叫作 smartptr&吧,裡面有個成員m_ptr,表示真正的指針,這個smartptr在釋構的時候會delete m_ptr(或者給m_ptr所指對象減計數)
有如下前提:
1. 同時它重載了 operator -&>,如有個實例smartptr& spDoc = ...; spDoc-&>open()實際上就是調用spDoc中的m_ptr-&>open()。(因為假設了用.代替"-&>",那麼就當成是重載了 operator .()吧)
2. smartptr&有個clear()表示清除m_ptr,即m_ptr = nullptr

這時候問題來了,sp是smartptr& 的一個實例,Object中恰好也有個clear()
那麼,如果統一用".",在調用 sp.clear()的時候是調用 smartptr&的clear()還是smartptr&中的m_ptr的clear()呢?
這樣就有二異性的問題了。


推薦閱讀:

面試 C++ 程序員,什麼樣的問題是好問題?
發現很多外掛和木馬編寫都是用MFC,MFC有必要學嗎?
如何看待阿里2016校招研發工程師筆試題題目?
用一年時間如何能掌握 C++ ?
如何通過自學找到一份開發的工作?

TAG:C |