C++筆記 第五十三課 被遺棄的多重繼承(上)---狄泰學院
阿新 • • 發佈:2018-12-01
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第五十三課 被遺棄的多重繼承(上)
1.問題
C++中是否允許一個類繼承自多個父類?允許
2.C++支援編寫多重繼承的程式碼
一個子類可以擁有多個父類
子類擁有父類的成員變數
子類繼承所有父類的成員函式
子類物件可以當做任意父類物件使用
多重繼承的語法規則
多重繼承的本質與單繼承相同!
53-1 多重繼承問題一
#include <iostream> #include <string> using namespace std; class BaseA { int ma; public: BaseA(int a) { ma = a; } int getA() { return ma; } }; class BaseB { int mb; public: BaseB(int b) { mb = b; } int getB() { return mb; } }; class Derived : public BaseA, public BaseB { int mc; public: Derived(int a, int b, int c) :BaseA(a), BaseB(b) { mc = c; } int getC() { return mc; } void print() { cout << "ma =" << getA() << "," << "mb =" << getB() << "," << "mc =" << mc << endl; } }; int main() { cout << "sizeof(Derived) = " << sizeof(Derived) << endl; //12 Derived d(1,2,3); d.print(); cout << "d.getA() = " << d.getA() << endl; cout << "d.getB() = " << d.getB() << endl; cout << "d.getC() = " << d.getC() << endl; cout << endl; BaseA* pa = &d; BaseB* pb = &d; cout << "pa->getA() = " << pa->getA() << endl; cout << "pb->getB() = " << pb->getB() << endl; cout << endl; void* paa = pa; void* pbb = pb; if( paa == pbb) { cout << "Pointer to the same object!" << endl; } else { cout << "Error" << endl; } cout << "pa = " << pa << endl; cout << "pb = " << pb << endl; cout << "paa = " << paa << endl; cout << "pbb = " << pbb << endl; return 0; } 執行結果 sizeof(Derived) = 12 ma =1,mb =2,mc =3 d.getA() = 1 d.getB() = 2 d.getC() = 3 pa->getA() = 1 pb->getB() = 2 Error pa = 0x7fffe245f4b0 pb = 0x7fffe245f4b4 paa = 0x7fffe245f4b0 pbb = 0x7fffe245f4b4
3.多重繼承問題一
通過多重繼承得到的物件可能擁有“不同的地址”!!
解決方案:無
實質:指向同一個物件的不同位置(一個指向頭,一個指向腿)
在這裡插入圖片描述
4.多重繼承的問題二
多重繼承可能產生冗餘的成員
53-2 多重繼承問題二
#include <iostream> #include <string> using namespace std; class People { string m_name; int m_age; public: People(string name, int age) { m_name = name; m_age = age; } void print() { cout << "Name = " << m_name << "," << "Age = " << m_age << endl; } }; class Teacher : virtual public People { public: Teacher(string name, int age) : People(name, age) { } }; class Student : virtual public People { public: Student(string name, int age) : People(name, age) { } }; class Doctor : public Teacher, public Student { public: Doctor(string name, int age) : Teacher(name + "1", age + 1), Student(name, age),People(name, age) { } }; int main() { Doctor d("Delphi", 33); //d.print(); d.Teacher::print(); d.Student::print(); return 0; } 執行結果 Name = Delphi,Age = 33 Name = Delphi,Age = 33
無論執行哪種方式,兩者結果是一樣的。
當多重繼承關係出現閉合時將產生資料冗餘的問題!!!
解決方案:虛繼承
虛繼承能夠解決資料冗餘問題
中間層父類不再關係頂層父類的初始化
最終子類必須直接呼叫頂層父類的建構函式
問題:當架構設計中需要繼承時,無法確定使用直接繼承還是虛繼承!!!
犧牲效率,犧牲移植性,架構師不喜歡多繼承,多重繼承僅作學術研究。
小結
C++支援多重繼承的程式設計方式
多重繼承容易帶來問題
可能出現“同一個物件的地址不同”的情況
虛繼承可以解決資料冗餘的問題
虛繼承的使得架構設計可能出現問題