C++
-
繼承的建構式、
-
一個類只繼承其直接基類(父類)的建構式、默認、拷貝、移動建構式是不能直接被繼承的、
-
using讓某個名字在當前作用區域內可見、
-
class a { public: a(int a1,int a2,int a3){} }; class b :public a { public: using a::a//繼承a的建構式、編譯到此時會把基類的每個建構式都生成一個與之相對應的派生類建構式、形參串列相同的派生類函式、函式體為空、 }; int main() { b ab(10, 20, 30); }
-
-
如果基類a的建構式有默認引數的話、編譯器遇到using a::a的時候、就會在派生類b中構造多個建構式、
-
其余的建構式、則每個分別省略掉一個默認引數、
-
class a { public: a(int a1,int a2,int a3=100){} }; class b :public a { public: using a::a;//編譯器會合成默認建構式、 }; int main() { b ab(10, 20); }
-
-
基類如果含有多個建構式、一般情況下派生類會繼承所有的這些建構式、
-
特殊不會繼承的情況、
- 派生類中定義的建構式與基類建構式相同的引數串列、基類中繼承的建構式會被派生類中定義覆寫掉、(只能繼承未被覆寫的部分)派生類優先于基類
- 默認、拷貝、移動建構式不會被繼承、
-
-
多重繼承、
-
多重繼承、
-
從多個父類來產生出子類、
-
派生類會包含每個基類的子物件、
-
class g { public: g(int i) :m(i) {} virtual~g() {} void mo() { cout <<m<< endl; } public: int m; }; class a :public g//繼承g { public: a(int i) :g(i), ma(i)//每個子類的建構式負責解決自己父類的初始化問題 {} virtual ~a() {} void mo() { cout << ma << endl; } public: int ma; }; class b //不繼承g { public: b(int i): mb(i) {} virtual ~b() {} void mo() { cout << mb << endl; } public: int mb;//定義 }; class c : public a, public b //class c:a,b//此為默認繼承、看c決定、c是struct還是class class則是privaate(私有)繼承、c是struct則是public(公用)繼承 { public: c(int a1, int a2, int a3) :a(a1), b(a2), mc(a3) {} virtual~c() {} void mC() { cout << mc << endl; a::mo();//呼叫a類中的mo函式 b::mo();//呼叫b類中的mo函式 } public: int mc;//定義成員 }; int main() { c ct(20, 3, 4); ct.mC(); ct.a :: mo();//增加作用域、明確系統該呼叫類a還是類b的成員函式 }
-
-
靜態成員變數、
-
靜態成員是屬于類而非是物件、
-
可以直接宣告、但是使用必須要定義、因為定義時分配記憶體、
-
class g { public: g(int i) :m(i) { } virtual~g() { } void mo() { cout <<m<< endl; } public: int m; public: static int mic;//宣告靜態成員、 }; int g::mic=3;//定義靜態成員并賦初值、可以不賦初值、 class a :public g//繼承g { public: a(int i) :g(i), ma(i)//每個子類的建構式負責解決自己父類的初始化問題 { } virtual ~a() { } void mo() { cout << ma << endl; } public: int ma; }; class b //不繼承g { public: b(int i): mb(i) { } virtual ~b() { } void mo() { cout << mb << endl; } public: int mb;//定義 }; class c : public a, public b //class c:a,b//此為默認繼承、看c決定、c是struct還是class class則是privaate(私有)繼承、c是struct則是public(公用)繼承 { public: c(int a1, int a2, int a3) :a(a1), b(a2), mc(a3) { } virtual~c() { } void mC() { cout << mc << endl; a::mo();//呼叫a類中的mo函式 b::mo();//呼叫b類中的mo函式 } public: int mc;//定義成員 }; int main() { c ct(20, 3, 4); ct.mC(); ct.a :: mo();//增加作用域、明確系統該呼叫類a還是類b的成員函式 g::mic = 30;//直接用類名來參考靜態變數、 //b::mic = 70;//不可以因為b沒有繼承g c::mic = 60;//可以是因為c繼承了a a::mic = 50;//可以是因為a繼承了g ct.mic = 20;//物件也可以參考、 }
-
-
派生類建構式與解構式、
-
構造一個派生類物件將同時構造并初始化私有的基類物件、
-
派生類的建構式初始化串列只初始化它的直接基類、每個類的建構式都負責初始化它的直接基類、
-
派生類建構式初始化串列將實參分別傳遞到每個直接基類、基類和派生類串列出現的順序保持一致、最先構造最后釋放、
-
class g { public: g(int i) :m(i) { cout << "執行g建構式" << endl; } virtual~g() { cout << "執行g解構式" << endl; } void mo() { cout <<m<< endl; } public: int m; }; class a :public g//繼承g { public: a(int i) :g(i), ma(i)//每個子類的建構式負責解決自己父類的初始化問題 { cout << "執行a建構式" << endl; } virtual ~a() { cout << "執行a解構式" << endl; } void mo() { cout << ma << endl; } public: int ma; }; class b //不繼承g { public: b(int i): mb(i) { cout << "執行b建構式" << endl; } virtual ~b() { cout << "執行b解構式" << endl; } void mo() { cout << mb << endl; } public: int mb;//定義 }; class c : public a, public b//派生串列 { public: c(int a1, int a2, int a3) :a(a1), b(a2), mc(a3) { cout << "執行c建構式" << endl; } virtual~c() { cout << "執行c解構式" << endl; } void mC() { cout << mc << endl; a::mo();//呼叫a類中的mo函式 b::mo();//呼叫b類中的mo函式 } public: int mc;//定義成員 }; int main() { c ct(20, 3, 4); -
顯示初始化基類和隱式初始化基類(不帶引數的建構式、默認建構式)、
-
-
從多個父類繼承建構式、
-
一個類從他的基類中繼承相同的建構式、該類就必須未該走建構式定義屬于自己的函式、
-
子類要定義同引數的自己建構式、
-
class a { public: a(int t) {}; }; class b{ public: b(int t) {}; }; class c:public a,public b { public: using a::a;//繼承a using b::b;//繼承b c(int t) :a(t), b(t) {};
-
-
-
虛基類、虛繼承
-
一般來說、派生串列中同一個基類只能出現一次、
-
派生類可以通過它的倆個直接基類分別繼承 同一個間接基類、
-
直接繼承某一個基類、然后通過另一個基類間接繼承該基類、
-
同一基類被繼承兩次會產生名字沖突(兩個名字)、虛繼承為此而生、
-
虛繼承無論出現多少次、派生類只包含一個共享的虛基類子內容、(就沒有名字沖突)、
-
虛繼承僅對子類所派生的子類有效、對基類派生的子類無效、
-
virtual——虛繼承、
-
虛基類由子類初始化父類的父類、最后的子類初始化最初的父類、如果d繼承了c則由d初始化g、
-
最低類的派生初始化最高的基類、在虛繼承中最先初始化虛繼承的類然后在按照派生串列來初始化其它的類、
-
虛基類的銷毀和構造順序相反、多個虛基類則追溯時初始化、
-
class g { public: g(int i) :m(i) { cout << "執行g建構式" << endl; } virtual~g() { cout << "執行g解構式" << endl; } void mo() { cout <<m<< endl; } public: int m; }; class a : virtual public g//虛基類 { public: a(int i) :g(i), ma(i) { cout << "執行a建構式" << endl; } virtual ~a() { cout << "執行a解構式" << endl; } void mo() { cout << ma << endl; } public: int ma; }; class j : virtual public g//虛基類 { public: j(int i) :g(i), ma1(i) { cout << "執行a1建構式" << endl; } virtual ~j() { cout << "執行a1解構式" << endl; } void mo() { cout << ma1 << endl; } public: int ma1; }; class b //不繼承g { public: b(int i): mb(i) { cout << "執行b建構式" << endl; } virtual ~b() { cout << "執行b解構式" << endl; } void mo() { cout << mb << endl; } public: int mb;//定義 }; class c : public a, public j, public b//class c:a,b//此為默認繼承、看c決定、c是struct還是class class則是privaate(私有)繼承、c是struct則是public(公用)繼承 { public: c(int a1, int a2, int a3) :a(a1),j(a1),g(a1), b(a2), mc(a3)//初始化g { cout << "執行c建構式" << endl; } virtual~c() { cout << "執行c解構式" << endl; } void mC() { cout << mc << endl; a::mo();//呼叫a類中的mo函式 b::mo();//呼叫b類中的mo函式 } public: int mc;//定義成員 }; int main() { //g* p = new c(23, 34, 33); c ct(20, 3, 4);//g會被繼承兩次、會產生名字沖突、 //ct.mo = 23;//虛繼承為了解決此沖突、虛繼承進隊c有效對a和j均無效 }
-
-
總結
- 慎用虛基類、容易出現二義性、
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/184351.html
標籤:C++
