日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

读书笔记《Effective C++》条款40:明智而审慎地使用多重继承

發布時間:2024/3/13 c/c++ 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读书笔记《Effective C++》条款40:明智而审慎地使用多重继承 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一旦涉及多重繼承,C++社群便分為兩個基本陣營。一派認為如果單一繼承是好的,多重繼承一定更好。另一派主張,單一繼承是好的,但多重繼承不值得使用。

最先需要認清的一件事是,當用到多重繼承,程序有可能從一個以上的base class繼承相同名稱(如函數、typedef等等),那會導致較多的歧義。例如:

class BorrowableItem { public:void checkOut(); };class ElectronGadget { private:bool checkOut() const; };class MP3Player : public BorrowableItem, public ElectronGadget {};MP3Player mp; mp.checkOut();//歧義:調用的是哪個checkOut? 注意此例中對checkOut的調用是有歧義的,即使兩個函數之中只有一個可取用(BorrowableItem內的checkOut是public,ElectronicGadget內的卻是private)。這與C++用來解析重載函數調用的規則相符:在看到是否有個函數可取用之前,C++首先確認這個函數對此調用之言是最佳匹配。找出最佳匹配函數后才檢驗其可取性。本例中的兩個checkOut函數有相同的匹配程度,沒有所謂最佳匹配。因此ElectronicGadget::checkOut的可取用性也就從未被編譯器審查。

為了解決這個歧義,必須明確指出要調用哪一個base class內的函數:

mp.BorrowableItem::checkOut();

多重繼承的意思是繼承一個以上的base class,但這些base class并不常在繼承體系中又有更高級的base class,那會導致要命的“鉆石型多重繼承”:

class File {}; class InputFile : public File {}; class OutputFile : public File {}; class IOFile : public InputFile, public OutputFile {};任何時候如果有一個繼承體系而其中某個base class和某個derived class之間有一條以上的相同路線,就必須面對這樣一個問題:是否打算讓base class內的成員變量經由每一條路徑被復制?假設File class有個成員變量fileName,那么IOFile內該有多少筆這個名稱的數據呢?從某個角度說,IOFile從其每一個base class繼承一份,所以其對象內應該有兩份fileName成員變量。但從另一個角度說,IOFile對象只該有一個文件名稱,所以它繼承自兩個base class而來的fileName不該重復。

C++對這兩個方案都支持——雖然其缺省做法是執行復制。如果那不是你想要的,你必須令那個帶有此數據的class(也就是File class)成為一個virtual base class。為了這樣做,必須令所有直接繼承自它的class采用“virtual繼承”:

class File {}; class InputFile : virtual public File {}; class OutputFile : virtual public File {}; class IOFile : public InputFile, public OutputFile {};

從正確行為的觀點看,public繼承應該總是virtual。但是為了避免繼承得來的成員變量重復,編譯器必須提供若干幕后工作,而其后果是:使用virtual繼承的那些class所產生的對象往往比使用non-virtual繼承的class體積大,訪問virtual base class的成員變量時,也比訪問non-virtual base class的成員變量速度慢。種種細節因編譯器不同而異,但基本重點很清楚:你得為virtual繼承付出代價。

virtual繼承的成本還包括其他方面。支配“virtual base class初始化”的規則比其non-virtual base的情況遠為復雜且不直觀。virtual base的初始化責任是有繼承體系中的最低層class負責。

忠告很簡單:第一,非必要不使用virtual base。平常請使用non-virtual繼承。第二,如果你必須使用virtual base class,盡可能避免在其中放置數據。這么一來就不需要擔心這些class身上的初始化(和賦值)所帶來的詭異事情了。Java和.Net的Interface值得注意,它在許多方面兼容于C++的virtual base class,而且也不允許含有任何數據。


要點:

1.多重繼承比單一繼承復雜。它可能導致新的歧義性,以及對virtual繼承的需要。

2.virtual繼承會增加大小、速度、初始化(及賦值)復雜度等等成本。如果virtual base class不帶任何數組,將是最具實用價值的情況。

3.多重繼承的確有正當用途。其中一個情節涉及“public繼承某個interface class”和“private繼承某個協助實現的class”的兩相組合。

總結

以上是生活随笔為你收集整理的读书笔记《Effective C++》条款40:明智而审慎地使用多重继承的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。