派生類不能直接訪問基類的私有成員,必須通過基類方法進行訪問。建立派生類物件時,首先建立基類物件。也就是說基類物件在程式進入派生類建構函式之前被建立。c++使用成員初始化列表來完成。派生類建構函式初始化基類私有成員,採用成員初始化列表。
總結:
首先,若基類函式需要被派生類重定義,則需要將其在基類宣告為虛函式。
虛函式必須完全一致,否則派生類將重定義函式,隱藏基類虛函式。返回值除外
析構函式須使用虛析構函式,防止因指標或引用型別導致析構錯誤物件。
虛函式採用動態聯編,不同位置虛函式存在不同位址,每個物件包含不同函式位址。
class_name::class_name(int a,int b, int c):base_class(a,b)
派生類建構函式要點:
首先建立基類物件
派生類建構函式應通過成員初始化列表將基類資訊傳遞給基類建構函式
派生類建構函式應初始化派生類新增的成員變數
注意:成員初始化列表只能用於建構函式
基類指標可以在不進行顯示型別轉換情況下指向派生類物件;基類引用可在不進行顯示型別轉換的情況下引用派生類物件。同樣也可以將派生類物件賦給基類物件。
基類指標或引用只能用於呼叫基類方法,因此不能使用其呼叫派生類方法。通常要求引用和指標型別與賦給的型別匹配,但這一規則對繼承來說是例外。不可以將基類物件和位址賦給派生類引用和指標。
概念:同乙個方法在派生類和基類中的行為是不同的,那麼方法的行為應取決於呼叫該方法的物件,稱為多型。
方法:
派生類中重新定義基類的方法
使用虛函式
要點:若要在派生類重新定義基類方法,通常將基類方法宣告(定義不需要)為虛函式。為基類宣告乙個虛析構函式也是一種慣例。
重定義基類方法
在基類和派生類中分別定義乙個同名函式,則根據物件型別來分別呼叫相應的函式。
結果為:class student
在基類和派生類分別定義了,若物件呼叫 如下:void print() {
cout << "呼叫student: "《可見函式print()
student s("liming", 13);
s.print();
grade g1(10, "lama", 20);
g1.print();
呼叫student: liming
呼叫grade: 10
方法通過引用或者指標而不是物件呼叫的,沒有使用virtual
定義,則根據引用型別或指標型別選擇方法。
呼叫如下:
student s("liming", 13);
s.print();
student *s1;
grade g1(10, "lama", 20);
student &s2 = g1;
s2.print();
s1 = &g1;
s1->print();
g1.print();
結果為:
呼叫student: liming
呼叫student: lama
呼叫student: lama
呼叫grade: 10
如果使用virtual
程式將根據引用或指標指向的物件型別來選擇方法。
將方法定義設定為:
virtual void print() {
cout << "呼叫student: "《則
student s("liming", 13);
s.print();
student *s1;
grade g1(10, "lama", 20);
student &s2 = g1;
s2.print();
s1 = &g1;
s1->print();
g1.print();
結果為:
呼叫student: liming
呼叫grade: 10
呼叫grade: 10
呼叫grade: 10
在使用new
和delete
的物件中,如果析構函式不是虛的,則只呼叫對應於指標型別的析構函式。
student *s1 = new grade(12, "ll", 17);
delete s1;
結果為:
呼叫student建構函式:
呼叫grade建構函式:
呼叫student析構函式
由此可見,並沒有呼叫派生類的析構函式。
若將基類析構函式設為vritual
,則結果如下:
呼叫student建構函式:
呼叫grade建構函式:
呼叫grade析構函式
呼叫student析構函式
所以應將析構函式設為虛析構函式。 繼承和多型二 虛析構函式
雖然我們已經知道了什麼是繼承和多型,也明白了多型依賴於繼承,但是在多型中存在哪些問題呢?多型中可能存在的記憶體洩露問題 例如下面的程式中,在圓形circle的類中定義乙個圓心的座標,並且座標是在堆中申請的記憶體,則在mian函式中通過基類指標操作派生類物件的成員函式是沒有問題的,可是在銷毀物件記憶體...
虛函式和多型(析構函式)
描述 1.定義乙個類animal,該類中包含資料成員name用來記錄動物的名字,並有乙個虛函式show用於顯示動物的種類。2 定義兩個類cat和dog,都繼承自animal 包含show函式,不但要顯示動物的種類 型別分別 為 cat,dog 還要顯示動物的名字。3 定義乙個tiger類,繼承自ca...
繼承與多型(四) 虛析構函式
當指向派生物件的指標被delete時,如果基類的析構函式是虛函式 應該如此 將執行正確的操作 呼叫派生類析構,呼叫基類析構。class mammal virtual mammal 需要被繼承的基類,析構函式都應該設定為虛函式,否則有可能無法析構基類 virtual void speak const ...