當我們使用基類的引用或指標呼叫基類中定義的乙個函式時,執行時才會知道他到底執行的哪個版本的函式。
而非虛函式或者通過物件呼叫時,編譯的時候就決定呼叫哪個版本的函式
#include using namespace std;
class pp1
virtual void print2()
};class pp : public pp1
void print2() override
};int main()
輸出結果:呼叫虛函式前,申明類ppp1
ppp2
pp1ppp2
auto* p = new pp();
p->print1();
p->pp1::print2();
虛函式後面加=0就是純虛函式,含有純虛函式的類是抽象基類,是不能直接建立物件的。
而且派生類必須給純虛函式定義,否則他們仍是抽象基類。
注:純虛函式不能在宣告裡定義,但可以在外部定義
介於public和private中間的字段:外部不可直接訪問,但是派生類內可以訪問
在對應的級別,使用using宣告語句
public:
using base::pri_data;
struct預設繼承public型別,class預設繼承pri型別。
最好宣告的時候,顯示的宣告出來。
c++11功能。通過【using 基類:基類】的寫法可以繼承基類的建構函式
注意:如果基類有預設實參,派生類不會繼承。派生類回生成多個建構函式,比如基類是乙個形參+乙個實參,派生類會生成乙個形參的建構函式+兩個形參的建構函式
注意2:預設、拷貝和移動建構函式不會被繼承
即使形參列表不同,派生類的同名成員也會隱藏掉基類的同名成員
多重繼承主要需要注意的就是成員的二義性。如果兩個基類有同乙個名稱的成員,需要在前面宣告類名。
構造順序:先父類,後子類
析構順序:先子類,後父類
解決問題:同乙個類多次繼承乙個類的問題。b、c分別繼承a,d繼承b、c,此時d繼承了兩次a。使用虛繼承可以確保在d中只有乙個a的基類部分。
虛基類:虛繼承某個類的類
虛派生只影響從指定了虛基類的派生類中進一步派生出的類,它不會影響派生類本身。
class raccoon : public virtual zooanimal {};
class bear : virtual public zooanimal {};
首先使用提供給最底層派生類建構函式的初始值初始化該物件的虛基類子部分,接下來按照直接基類在派生列表**現的次序依次對其進行初始化。
比如上面的abcd。構造順序是:a->b->c->d
如果未宣告虛基類,構造順序是:a->b->a->c->d
虛函式總是先於非虛基類構造,與他們在繼承體系中的次序和位置無關和構造順序相反
如果不希望該類被其他類給繼承,就在類名後申明final
class last final
如果不希望該方法被派生類給覆蓋,就在方法後申明final
struct a
如果寫的函式沒有覆蓋到基類的虛函式,會報錯
如果基類中的三個建構函式或析構函式是刪除或不可訪問的,則派生類對應成員將是被刪除的
如果基類析構函式不可訪問或刪除,則派生類中【合成】的預設和拷貝建構函式將是刪除的
如果基類的移動函式是刪除的,則派生類中該函式將是刪除的。基類的析構函式如果是刪除的同理
定義析構函式將阻止合成移動操作
如果已經定義了拷貝相關函式,那麼就不會生成移動相關操作;反之亦然
當乙個類擁有多個基類時,有可能出現派生類從兩個或更多基類中繼承了同名成員的情況。此時,不加字首限定符直接使用該名字將引發二義性
C 學習筆記八
24 子物件 當乙個類的成員時另乙個類的物件時,該物件就為子物件。子物件即是物件的成員 當類中出現了子物件 物件成員 該類的建構函式要包含對子物件的初始化,通常採用成員初始化列表的方法來初始化子物件 include class a void print class b 成員初始化列表,私有成員可以通...
C 學習筆記(八)
類 類的建構函式和析構函式 this指標 物件陣列 1.c 區別於c語言的物件導向特性 抽象 封裝和資料隱藏 多型 繼承 的可重用性 2.封裝 將實現細節放在一起並將它們與抽象分開。3.資料隱藏 將資料放在類的私有部分中 是一種封裝。資料隱藏可以是資料變的安全,同時使得類的使用者無需關心資料是被如何...
c 學習筆記八
函式 1 函式的過載 函式名相同,引數個數不同 引數個數相同,引數型別不同 函式的簽名 過載和指標引數 例如 int temp int pnum1,int pnum2 int temp long pnum1,long pnum2 過載和引用引數 過載和const引數 2 函式模板 乙個簡章的函式模版...