在初步探索了C++繼承的語言特性之後,總結下其賦值兼容規則:
1.子類對象可以賦值給父類對象(切割/切片)
在公有繼承的前提下,子類是可以賦值給父類對象的,爲什麼是共有繼承(public),因爲公有繼承會產生“is-a”的關係,這種關係會導致子類中有結構的嵌套這父類的信息,。所以子類可以給父類賦值,期間會發生類似降級的事情,使得賦值成功。若爲私有繼承,則會產生“has-a”的關係,這種關係是從屬關係,基類中的數據僅僅是包含在派生類中,若賦值,則不會產生類似於降級的事情發生,編譯器會報錯。代碼如下:
#include<iostream> using namespace std; class A { public: A() :_num(0) { } private: int _num; }; class B:private A { public: B() :A() { } private: }; int main() { B b; A a; a = b;//錯誤,has-a關係無法賦值 return 0; } #include<iostream> using namespace std; class A { public: A() :_num(0) { } private: int _num; }; class B:public A { public: B() :A() { } private: }; int main() { B b; A a; a = b;//正確,is - a關係可以賦值 return 0; }
2.父類對象不能賦值給子類對象
父類對象給子類對象賦值會造成父類對象的成員變量並不能完全覆蓋到子類對象的成員變量,這種做法存在很大的安全問題,編譯器是不允許的。
3.父類的指針/引用可以指向子類對象
這種做法是可行的,但產生的父類只能訪問到父類所有的內容,子類的內容也會保留下來,若要訪問,則只能依靠指針的偏移做到,並不能直接訪問,浪費資源。
4.子類的指針/引用不能指向父類對象(可以通過強制類型轉換完成)
這樣的做法是編譯器允許的,但是存在很大的安全問題,若通過強制類型轉換,會非常容易發生越界問題,這裏我們不提倡。