C++ 多態(tài)性 虛函數(shù)、抽象類(二)

注意:本文中代碼均使用 Qt 開發(fā)編譯環(huán)境

在C++中不能聲明虛構(gòu)造函數(shù)爱沟,但是可以聲明虛析構(gòu)函數(shù)帅霜。析構(gòu)函數(shù)沒有類型,也沒有參數(shù)呼伸,和普通成員函數(shù)相比身冀,虛析構(gòu)函數(shù)相對簡單。
語法:

virtual ~className();

如果有可能通過基類指針調(diào)用對象的析構(gòu)函數(shù)(通過delete)括享,并且被析構(gòu)的對象是有重要的析構(gòu)函數(shù)的派生類的對象闽铐,就需要讓基類的析構(gòu)函數(shù)成為虛函數(shù)。

未使用虛析構(gòu)函數(shù)的情況舉例:

#include <QCoreApplication>
#include <QDebug>

class Base{
public:
    ~Base(){ qDebug() << "Basedestructor"; }
};

class Derived: public Base{
public:
    Derived();
    ~Derived();
private:
    int * i_pointer;
};

Derived::Derived(){
    i_pointer = new int(0);
}

Derived::~Derived(){
    qDebug() << "Derived destructor";
    delete i_pointer;
}

void fun(Base *b){
    delete b;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Base *b= new Derived();
    fun(b);

    return a.exec();
}

本例使用了Qt5.8的開發(fā)和編譯環(huán)境奶浦,因此有一些Qt中的輸出log的方法兄墅,上述測試代碼的輸出為:

Basedestructor

這說明,通過基類指針刪除派生類對象時調(diào)用的是基類的析構(gòu)函數(shù)澳叉,派生類的析構(gòu)函數(shù)沒有被執(zhí)行隙咸,因此派生類對象中動態(tài)分配的內(nèi)存空間沒有被釋放沐悦,造成了內(nèi)存泄漏。

避免上述情況的方法就是將基類的析構(gòu)函數(shù)聲明為虛函數(shù):

class Base{
public:
    virtual ~Base(){ qDebug() << "Basedestructor"; }
};

運行結(jié)果為:

Derived destructor
Basedestructor

這說明派生類的析構(gòu)函數(shù)被調(diào)用了五督,派生類對象中動態(tài)申請的內(nèi)存空間被正確的釋放了藏否。這是由于使用了虛析構(gòu)函數(shù),實現(xiàn)了多態(tài)充包。

《抽象類》

抽象類是一種特殊的類副签,他為一個類族提供統(tǒng)一的操作界面。抽象類是為了抽象和設(shè)計的目的而建立的基矮,可以說淆储,建立抽象類,就是為了通過它多態(tài)地使用其中的成員函數(shù)家浇。抽象類處于類層次的上層本砰,一個抽象類自身無法實例化,也就是說我們無法定義一個抽象類的對象钢悲,只能通過繼承機制点额,生成抽象類的非抽象派生,然后再實例化莺琳。

<純虛函數(shù)>

純虛函數(shù)是一個在基類中聲明的虛函數(shù)还棱,它在該基類中沒有定義具體的操作內(nèi)容,要求派生類根據(jù)實際需要定義自己的版本惭等,聲明格式:

virtual returnType functionName(params) = 0;

實際上珍手,它與一般虛函數(shù)成員的原型在書寫格式上的不同就在于后面加了“=0”。聲明為純虛函數(shù)之后咕缎,基類中就不再給出函數(shù)的實現(xiàn)部分珠十。純虛函數(shù)的函數(shù)體由派生類給出料扰。

還有一種情況是函數(shù)體為空的虛函數(shù)凭豪,請注意它和純虛函數(shù)的區(qū)別。純虛函數(shù)根本就沒有函數(shù)體晒杈,而空的虛函數(shù)的函數(shù)體為空嫂伞,前者所在的類是抽象類,不能直接進行實例化拯钻,而后者所在的類是可以實例化的帖努。他們共同的特點是都可以派生出新的類,然后在新的類中給出虛函數(shù)的實現(xiàn)粪般,而且這種新的實現(xiàn)可以具有多態(tài)特征拼余。

<抽象類>

帶有純虛函數(shù)的類就是抽象類。抽象類的主要作用就是通過它為一個類族建立一個公共接口亩歹,使它們能夠更有效地發(fā)揮多態(tài)特性匙监。抽象類聲明了一族派生類的共同接口凡橱,而接口的完整實現(xiàn),即純虛函數(shù)的函數(shù)體亭姥,要由派生類自己定義稼钩。

抽象類派生出新的類之后,如果派生類給出所有純虛函數(shù)的函數(shù)實現(xiàn)达罗,這個派生類就可以定義自己的對象坝撑,因而不再是抽象類;反之粮揉,如果派生類沒有給出所有純虛函數(shù)的函數(shù)實現(xiàn)巡李,這時派生類仍然是一個抽象類。

抽象類不能實例化滔蝉,即不能定義一個抽象類的對象击儡,但是,我們可以聲明一個抽象類的指針和引用蝠引。通過指針或引用阳谍,我們就可以指向并訪問派生類對象,進而訪問派生類的成員螃概,這種訪問是具有多態(tài)特征的矫夯。

示例:

#include <QCoreApplication>
#include <QDebug>

class B {
public:
    virtual void display() = 0;
};

class C: public B {
public:
    void display() { qDebug() << "C::display()"; }
};

class D: public C {
public:
    void display() { qDebug() << "D::display()"; }
};

void fun(B *ptr) {
    ptr->display();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    B *p;
    C c;
    D d;
    p = &c; fun(p);
    p = &d; fun(p);

    return a.exec();
}

該測試示例的輸出結(jié)果是:

C::display()
D::display()

同時,程序中派生類的虛函數(shù)并沒有用關(guān)鍵字virtual顯示說明吊洼,因為它們與基類的純虛函數(shù)具有相同的名稱训貌、參數(shù)及返回值,由系統(tǒng)自動判斷確定其為虛函數(shù)冒窍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末递沪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子综液,更是在濱河造成了極大的恐慌款慨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谬莹,死亡現(xiàn)場離奇詭異檩奠,居然都是意外死亡,警方通過查閱死者的電腦和手機附帽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門埠戳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蕉扮,你說我怎么就攤上這事整胃。” “怎么了喳钟?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵屁使,是天一觀的道長欠啤。 經(jīng)常有香客問我,道長屋灌,這世上最難降的妖魔是什么洁段? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮共郭,結(jié)果婚禮上祠丝,老公的妹妹穿的比我還像新娘。我一直安慰自己除嘹,他們只是感情好写半,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尉咕,像睡著了一般叠蝇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上年缎,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天悔捶,我揣著相機與錄音,去河邊找鬼单芜。 笑死蜕该,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洲鸠。 我是一名探鬼主播堂淡,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼扒腕!你這毒婦竟也來了绢淀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘾腰,失蹤者是張志新(化名)和其女友劉穎皆的,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體居灯,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡祭务,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年内狗,在試婚紗的時候發(fā)現(xiàn)自己被綠了怪嫌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡柳沙,死狀恐怖岩灭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赂鲤,我是刑警寧澤噪径,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布柱恤,位于F島的核電站,受9級特大地震影響找爱,放射性物質(zhì)發(fā)生泄漏梗顺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一车摄、第九天 我趴在偏房一處隱蔽的房頂上張望寺谤。 院中可真熱鬧,春花似錦吮播、人聲如沸变屁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粟关。三九已至,卻和暖如春环戈,著一層夾襖步出監(jiān)牢的瞬間闷板,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工院塞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛔垢,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓迫悠,卻偏偏與公主長得像鹏漆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子创泄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容