標籤:內容 col clu 形參 方式 玩遊戲 函數對象 using eal
01、繼承:
#include <iostream>using namespace std;/* 回顧上節的內容: const 重載 運算子多載 -> () 函數對象 今天的內容 繼承 比如: 人 -->身高 年齡 ...吃飯 睡覺 打豆豆 --> 成員函數 成員變數 小學生 吃飯 睡覺 打豆豆 寫作業 上學 身高 年齡 學號 大學 吃飯 睡覺 大打豆豆 談戀愛 寫論文 玩遊戲 學習 身高 年齡 績點 幾個類 -->相似的屬性 行為 繼承 某個類 繼承一個類(基類/父類)中所有的成員(成員變數/函數)加上自己的屬性/行為成為一個新的類(衍生類別/子類) 繼承: 1.吸收父類成員(除去構造和析構) 子類會吸收父類的所有成員 2.調整父類的成員 2.1存取控制 2.1.1 繼承方式 public private protected 2.1.2 父類的成員 public private protected 存取權限 private < protected < public 父類的 private 成員 子類中不能訪問 其餘的成員 就按照繼承方式中最安全的一種 作為子類的屬性 繼承方式 預設私人 2.2 隱藏 子類中定義一個父類相同的成員變數或者成員函數 //父類中的成員函數或者變數就會被隱藏 通過子類對象訪問 訪問到的是新的函數/變數 //隱藏的是父類繼承過來的函數和成員(子類中生效) //如果說子類中的函數和父類繼承的函數 函數名相同 參數不一樣 繼承的函數和新寫的函數構造重載 //子類不影響父類 3.添加新成員 子類中添加新成員變數/函數 實現新功能 基類 構造 析構 -->沒辦法繼承 子類要寫自己的構造和析構 子類的構造: 1.它必須調用父類的建構函式 (如果沒有顯示調用 那麼就隱性調用了預設的建構函式) 2.需要顯示調用 必須使用初始化形參列表 3.先調用父類構造 然後在調用子類構造 4.調用順序和形參列表中的順序無關 子類的析構: 1.析構會調用父類的析構 先調用子類析構 然後調用父類析構 2.可以預設調用 不需要顯示調用 父類的函數 可以訪問父類的成員 修改 訪問父類中的私人成員 --> 父類公有函數訪問 多繼承: 一個類繼承多個父類 //開發效率 -->提高的開發效率*///=======================================類函數====================================class father{private: int weight; // 體重 float height; // 身高public: int wealth; father(){ cout << "father的構造" << endl; } father(int x, float y, int z) :weight(x), height(y), wealth(z) { } ~father(){ cout << "father的析構" << endl; } void play(){ cout << "father的play" << endl; } void eat(){ cout << "father的eat" << endl; }};class son:public father // 後面是繼承父類: // 1.父類不是只有一個子類; // 2.子類可能不止有一個父類 // 如果是繼承多個父類 逗號隔開{public: int age; // 年齡 float height; // 身高 int wealth; son():father() // 調用了父類的建構函式 { cout << "調用了子類的建構函式" << endl; // weight; 父類的私人成員 子類中不能訪問 //eat(); // 調用父類中eat() } /** 父類的成員 -->父類的建構函式 初始化 子類 初始化子類的成員 子類 繼承了父類的成員 -->繼承過來的成員 可以重新賦值 */ son(int x, float y, int z) :age(x), height(y), wealth(z), father(x,y,z) // 有參構造 { } void play(){ cout << "son的play" << endl; }};int main(){ father ft; cout << sizeof(ft) << endl; son sn; cout << sizeof(sn) << endl; sn.height; sn.eat(); sn.play(); getchar(); return 0;}
02、多繼承:
#include <iostream>using namespace std;/* 多繼承 繼承兩個或者多個基類的所有成員 1.繼承 子類會調用父類的建構函式 調用順序只和繼承順序相關 2.析構 和建構函式順序相反 3.要訪問某個類繼承過來的成員 基類名::成員名 訪問(注意存取權限)菱形繼承 A派生B和C B和C共同派生D D就有來自A的兩份拷貝(一份來自B 一份來自D) 虛繼承 主要解決菱形繼承 (關鍵字:virtual) 虛繼承不影響B和C 影像的是D 如果B 和C 只有一個加virtual 那麼和繼承順序有關 一般的話 不建議使用多繼承*/class fruit // 水果{public: int color; fruit(){ cout << "水果類的建構函式" << endl; } ~fruit(){ cout << "水果類的建構函式" << endl; } void eat() { cout << "可以生吃" << endl; }};class vegetable // 蔬菜{public: int color; vegetable(){ cout << "蔬菜類的建構函式" << endl; } ~vegetable(){ cout << "蔬菜類的建構函式" << endl; } void cook() { cout << "煮熟吃" << endl; }};class tomato :public fruit, public vegetable // 多繼承 用逗號隔開{ // 先構造水果類 然後構造蔬菜類public: int color; tomato() :vegetable(), fruit() { /** 構造中初始化形參列表順序 不影響調用順序 */ } void see() { vegetable::color = 2; // 從類vegetable中繼承的color fruit::color = 5; color = 6; cout << vegetable::color << fruit::color << color << endl; }};//================================================例子=============================================class A{public: int x;};class B :virtual public A{};class C :virtual public A{};/* 車 四個輪子 -->B四個輪子 C四個輪子 -->D 8個輪子*/class D :public B, public C{public: void print() { B::x = 3; // 虛繼承 在最終的孫子類中 只留一個祖父類的拷貝 C::x = 4; cout << B::x << C::x << x << endl; }};int main(){ D d; d.print(); { tomato ta; ta.cook(); // 煮熟吃 ta.eat(); // 生吃 ta.see(); } getchar(); return 0;}/* 作業: 人類 身高 體重 吃飯睡覺 男人類 運動 學生類 學習 考試 -->派生出 男學生類 列印出吃飯睡覺 // 預防菱形繼承*/
<C++ - 繼承01> 2018-01-22