繼承
為什麼要有繼承??
有些時候,我們要寫好幾段功能相似但又不同的**,但是這些功能相似的**重複的去寫,就會顯得冗餘,這時就可以將這段**分離出來,再讓其他想要使用這段功能的類直接繼承即可使用,而不出現冗餘**,提高了效率。
在c++中,繼承又分為單繼承和多繼承。單繼承比多繼承要簡單的多。
繼承的特點
1、析構時先析構子類的,再析構父類的
2、派生類的建構函式應在其初始化表裡呼叫基類的建構函式。
3、在編寫派生類的賦值函式時,注意不要忘記對基類的資料成員重新賦值
4、派生類不可能繼承基類的建構函式、析構函式、賦值函式
5、基類的私有成員在派生類中不可見
6、is-a:在public繼承下產生的,因為乙個子類就是父類
7、has-a:在私有和保護繼承下出現,不支援賦值相容規則
何為賦值相容規則:
1.子類物件可以賦值給父類物件(切割/切片)
2. 父類物件不能賦值給子類物件
3. 父類的指標/引用可以指向子類物件
4. 子類的指標/引用不能指向父類物件(可以通過強制型別轉換完成)
單繼承:只有乙個父類
多繼承:有兩個或兩個以上父類,多繼承裡又包含了乙個菱形繼承
單繼承的方式如下:
class a
private:
int _a;
};class b : public a
private:
int _b;
};int main()
~繼承的關鍵符號為:(乙個冒號),後面再跟上限定修飾符以及要繼承的父類類名。
~子類如果和父類有相同的成員函式,子類在呼叫時會先呼叫自己的成員函式。這叫就近原則
繼承有幾個原則:
1、子類物件可以賦值給父類物件,但是父類物件不能賦值給子類物件。
2、父類的指標/引用可以指向子類物件,子類物件的指標/引用不能指向父類物件。
當編譯器足夠強大時,當我們把父類賦值給子類時,會直接在語句下面出現一條紅波浪線告訴我們不能這樣使用。
多繼承:
class a
private:
int _a;
};class b
private:
int _b;
};class c : public a, public b
private:
int _c;
};int main()
多繼承時,在子類的類名後面加上多個父類,父類中間用逗號隔開。如果子類的成員函式與父類的相同,如果想要訪問父類的成員函式,需要指定類域才能進行訪問。
菱形繼承
如此便是菱形繼承,我們可以很明顯的看到在最後的子類d中存在著兩個相同的a類,我們稱為這為冗餘。並且在程式呼叫時會產生二義性,即程式不知道該呼叫哪乙個父類裡面的a。
那麼該如何解決多重繼承裡出現的這種問題??這裡就引出了虛繼承的概念。
虛繼承:關鍵字:virtual
如何為虛繼承??
*在宣告派生類時,將關鍵字 virtual 加到相應的繼承方式前面。經過這樣的宣告之後,當基類通過多條派生路徑被乙個派生類繼承時,該派生類只繼承一次該基類的成員。
虛繼承雖然解決了問題,但是在一般情況下最好還是不用菱形繼承的好,因為沒有菱形繼承就不會有虛繼承。所以我們盡量在寫**時避免出現菱形繼承。
明智而審慎的使用Private繼承
c 如何將public繼承視為is a。private繼承並意味著 is a 如果類之間的繼承關係是private。編譯器不會自動將乙個derived物件轉換成乙個base classes。這和public繼承的情況不同。由private base classes繼承而來的所有成員,在derived...
條款39 明智的使用private繼承
首先看一下private繼承的法則 class之間的繼承關係如果是private的話,那麼編譯器不會將乙個derived物件自動當作為乙個base class物件。從base class繼承而來的所有方法以及屬性,在derived class都會變成是private的。private繼承的底層含義實...
明智而審慎的使用private繼承
private繼承的兩條規則 1 編譯器不會將乙個derived class轉化為baseclass,但是卻可以顯示轉換。也就是,他們之間不是is a的關係。2 從基類繼承的所有的成員和方法都將變為private屬性。也就是,它只繼承實現,不整合介面。private繼承意味著 根據某物實現出 它和復...