c++設計三種不同繼承方式的意義是什麼?
之前一直寫C,想學習一下C++,我現在大概知道public,protected,private繼承的區別,但是不是很理解C++這樣設計的目的和意義是什麼?
Bjarne 深受劍橋 CAP 系統的影響,在 C with Classes 時期就加入了 private 和 public 的區別。正好達到了「private 繼承只繼承實現;public 繼承還繼承介面」的效果。
protected 繼承則和 protected 成員一樣,是 Release 1.0 時候 Mark A. Linton 為了實現 Interviews GUI 庫請求 Bjarne 加進 C++ 的概念。不過諷刺的是,五年後 Mark 又在自己的項目里全面禁用了 protected 特性,理由是會帶來各種 Bug 難以維護。
---
題主有為什麼「設計成讓你看到,卻不讓你訪問」的疑問:
早在 The Annotated C++ Reference Manual 中就有提到,這裡 public / private / protected 保護的都是「Access」而非「Visibility」。
至於為何保護 Access 而非 Visibility,在 The Design and Evolution of C++ 中有相關的解釋:Why did I define it that way, and was it the right choice? My recollection on this point is vague, and the stored records are of no use. One point I do remember from the discussion at the time is that given the example above, the rule adopted ensures that f()s reference to a refers to the same a independently of what access is declared for X::a. Making public/private control visibility, rather than access, would have a change from public to private quietly change the meaning of the program from one legal interpretation (access X::a) to another (access the global a). I no longer consider this argument conclusive (If I ever did), but the decision made has proven useful in that it allows programmers to add and remove public and private specifications during debugging without quietly changing the meaning of programs. I do wonder if this aspect of the C++ definition is the result of a genuine design decision. It could simply be a default outcome of the preprocessor technology used to implement C with Classes that didnt get reviewed when C++ was implemented with more appropriate compiler technology.
- 這樣的話,變數引用的對象不會因為 public / private 的改變而改變,所以
- 不會被人說是坑
- 方便調試
- 早期預處理器的行為
public就是java,C#等等語言裡面的介面繼承,子類可以重寫父類的虛方法,父類指針可以引用子類,基本上大部分講OO的繼承相關特性都是指這種繼承方式下的特性一般來說,private繼承基本跟將父類包含為一個private屬性區別很小,所以很多語言中也沒必要像C++一樣實現這麼個東西,大概唯一一個區別就是,子類可以重寫父類的虛方法,這樣通過「子類方法-&>父類方法-&>父類虛方法」調用鏈時,最後可以調用到子類重寫的方法中protected繼承……一般很少用,可以看做是前兩者的折中吧,子類繼承的父類非private方法可以讓自己的子類看到
最終目的是為了滿足面向介面編程的要求,隔離介面與實現,控制那些人可以看到那一個級別的抽象。
去看Effective C++class A:Bpublic繼承表示——A是一種(is a)Bprivate繼承表示——A根據B實現(A is implemented in terms of B)protected繼承沒有什麼物理上的意義
public繼承就是我們其他面向對象語言,如Java CSharp中的繼承,滿足A is B,可以用B的引用來調用A,符合替換原則,如同直升機是飛行器,飛行器可以做到的直升機都可以做到。
private繼承不符合替換原則,也就是說,如果A私有繼承了B,那麼對於這種語句B* b = new A()是非法的。它的作用在於,子類的實現用了基類的方法,但是,子類並不是基類。如空調壓縮機可能用了電扇的實現,但是空調並不是電扇。
protected繼承意義不明,不推薦使用。控制可見性,所謂的不同層級的封裝性
讓被看到的那個類放心(我的東西你別瞎jb亂動)
讓看別人的那個類安心(你的那些破玩意看來我不用care)個人覺得如果是自己一個人寫個小程序,三者差別不大,甚至全是public都沒啥,只要記得變數和函數名,在派生類里不出現重名就可以,當然也可以(virtual)。然後程序大了一點但是為了派生類變數啥的訪問方便,設計為protected也沒啥,同樣最好記住變數和函數名。但是如果多人合作寫個大程序,最好是能private就private吧,免得別人和你用了一樣的名字啥的,導致程序出錯……然後各種麻煩。
所以呢,個人覺得,平常練手的時候,能夠private的就私有吧,養成習慣會好一點呃,c++初學者,以上為個人見解,歡迎指正因為寫程序往往不是一個人,即使是一個人寫後面忘了前面這也是難免的。為了防止出錯就有了public protected private這三個關鍵字,防止有人亂用代碼搞錯許可權。
繼承里用這些關鍵詞也是這個。推薦閱讀:
※如果讓我推薦編程語言的話(一)
※如果編程語言是女孩,你會選擇哪一個?
※如何最快速的提高閱讀英文技術文檔的能力?
※世界範圍內,有哪些用 Ruby 開發的優秀網站?
