亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

虛析構函數(√)、純虛析構函數(√)、虛構造函數

系統 1584 0

一. 虛析構函數


我們知道,為了能夠正確的調用對象的析構函數,一般要求具有層次結構的頂級類定義其析構函數為虛函數。因為在delete一個抽象類指針時候,必須要通過虛函數找到真正的析構函數。

如:

class Base
{
public :
Base(){}
virtual ~ Base(){}
};

class Derived: public Base
{
public :
Derived(){ };
~ Derived(){ };
}

void foo()
{
Base
* pb;
pb
= new Derived;
delete pb;
}
這是正確的用法,會發生動態綁定,它會先調用Derived的析構函數,然后是Base的析構函數

如果析構函數不加virtual,delete pb只會執行Base的析構函數,而不是真正的Derived析構函數。
因為不是virtual函數,所以調用的函數依賴于指向靜態類型,即Base

二. 純虛析構函數
現在的問題是,我們想把Base做出抽象類,不能直接構造對象,需要在其中定義一個純虛函數。如果其中沒有其他合適的函數,可以把析構函數定義為純虛的,即將前面的CObject定義改成:
class Base
{
public :
Base(){}
virtual ~ Base() = 0
};
可是,這段代碼不能通過編譯,通常是link錯誤,不能找到~Base()的引用 (gcc的錯誤報告)。這是因為,析構函數、構造函數和其他內部函數不一樣,在調用時,編譯器需要產生一個調用鏈。也就是,Derived的析構函數里面 隱含調用了Base的析構函數。而剛才的代碼中,缺少~Base()的函數體,當然會出現錯誤。

這里面有一個誤區,有人認為,virtual f()=0這種純虛函數語法就是沒有定義體的語義。
其實,這是不對的。這種語法只是表明這個函數是一個純虛函數,因此這個類變成了抽象類,不能產生對象。我們 完全可以為純虛函數指定函數體 ( http://www.research.att.com/~bs/bs_faq2.html#pure-virtual )。 通常的純虛函數不需要函數體,是因為我們一般不會調用抽象類的這個函數,只會調用派生類的對應函數。這樣,我們就有了一個純虛析構函數的函數體,上面的代碼需要改成:
class Base
{
public :
Base()
{
}
virtual ~ Base() = 0 ; // pure virtual
};

Base::
~Base () // function body
{
}

從語法角度來說,不可以將上面的析構函數直接寫入類聲明中(內聯函數的寫法)。這或許是一個不正交化的地方。但是這樣做的確顯得有點累贅

這個問題看起來有些學術化,因為一般我們完全可以在Base中找到一個更加適合的函數,通過將其定義為沒有實現體的純虛函數,而將整個類定義為抽象類。但這種技術也有一些應用,如這個例子:
class Base // abstract class
{
public :
virtual ~ Base(){}; // virtual, not pure
virtual void Hiberarchy() const = 0 ; // pure virtual
};

void Base::Hiberarchy() const // pure virtual also can have function body
{
std::cout
<< " Base::Hiberarchy " ;
}

class Derived : public Base
{
public :
Derived(){}
virtual void Hiberarchy() const
{
CB::Hiberarchy();
std::cout
<< " Derived::Hiberarchy " ;
}
virtual void foo(){}
};


int main(){
Base
* pb = new Derived();
pb
-> Hiberarchy();
pb
-> Base::Hiberarchy();
return 0 ;
}

在 這個例子中,我們試圖打印出類的繼承關系。在根基類中定義了虛函數Hiberarchy,然后在每個派生類中都重載此函數。我們再一次看到,由于想把 Base做成個抽象類,而這個類中沒有其他合適的方法成員可以定義為純虛的,我們還是只好將Hiberarchy定義為純虛的。(當然,完全可以定 義~Base函數,這就和上面的討論一樣了。^_^)

另外,可以看到,在main中有兩種調用方法,第一種是普通的方式,進行動態鏈接,執行虛函數,得到結果"Derived::Hiberarchy";第二種是指定類的方式,就不再執行虛函數的動態鏈接過程了,結果是"Base::Hiberarchy"。

通過上面的分析可以看出, 定義純虛函數的真正目的是為了定義抽象類 , 而并不是函數本身。與之對比,在java中,定義抽象類的語法是 abstract class,也就是在類的一級作指定(當然虛函數還是也要加上abstract關鍵字)。是不是這種方式更好一些呢?在Stroustrup的《C++語 言的設計與演化》中我找到這樣一段話:

“我選擇的是將個別的函數描述為純虛的方式,沒有采用將完整的類聲明定義為抽象的形式,這是因為純虛函數的概念更加靈活一些。我很看重能夠分階段定義類的能力;也就是說,我發現預先定義一些純虛函數,并把另外一些留給進一步的派生類去定義也是很有用的”。

我 還沒有完全理解后一句話,我想從另外一個角度來闡述這個概念。那就是,在一個多層復雜類結構中,中間層次的類應該具體化一些抽象函數,但很可能并不是所有 的。中間類沒必要知道是否具體化了所有的虛函數,以及其祖先已經具體化了哪些函數,只要關注自己的職責就可以了。也就是說,中間類沒必要知道自己是否是一 個真正的抽象類,設計者也就不用考慮是否需要在這個中間類的類級別上加上類似abstract的說明了。

當然,一個語言的設計有多種因素,好壞都是各個方面的。這只是一個解釋而已。

最后,總結一下關于虛函數的一些常見問題:

1) 虛函數是動態綁定的,也就是說,使用虛函數的指針和引用能夠正確找到實際類的對應函數,而不是執行定義類的函數。這是虛函數的基本功能,就不再解釋了。

2) 構造函數不能是虛函數 。而且, 在構造函數中調用虛函數,實際執行的是父類的對應函數 ,因為自己還沒有構造好, 多態是被disable的。

3) 析構函數可以是虛函數 ,而且,在一個復雜類結構中,這往往是必須的。

4) 將一個函數定義為純虛函數,實際上是將這個類定義為抽象類,不能實例化對象。

5) 純虛函數通常沒有定義體,但也完全可以擁有

6) 析構函數可以是純虛的,但 純虛析構函數必須有定義體 ,因為析構函數的調用是在子類中隱含的。

7) 非純的虛函數必須有定義體,不然是一個錯誤。

8) 派生類的override虛函數定義必須和父類完全一致。 除了一個特例,如果父類中返回值是一個指針或引用,子類override時可以返回這個指針(或引用)的派生 。例如,在上面的例子中,在Base中定義了 virtual Base* clone(); 在Derived中可以定義為 virtual Derived* clone()。可以看到,這種放松對于Clone模式是非常有用的。

虛析構函數(√)、純虛析構函數(√)、虛構造函數(X)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 97se亚洲国产综合自在线 | 黄色的网站在线观看 | 狠狠热精品免费观看 | 成人国产在线视频 | 久久老色鬼天天综合网观看 | 五月天中文在线 | 一级特级女人18毛片免费视频 | 国产乱叫456在线 | 免费看国产精品久久久久 | 亚洲影院中文字幕 | 第四色婷婷基地 | 欧美一级亚洲一级 | 青青青在线视频播放免费 | 青青青国产免费手机视频在线观看 | 七次郎在线视频精品视频 | 久久这里精品 | 日本欧美精品 | 日本中文字幕有码 | 久久国产精品男女热播 | 欧美一区二区三区久久久人妖 | 日本黄页在线观看 | 黄色片网站大全 | 一区二区三区精品国产 | 欧美一级特黄真人毛片 | 亚洲 欧美 日韩 在线 香蕉 | 香蕉成人在线视频 | 草久视频| 久热精品香蕉在线视频 | 精品一区二区三区的国产在线观看 | 性欧美xo视频在线观看 | 中文字幕一区二区三区精彩视频 | 欧美性精品hd在线观看 | 福利影院在线 | 超碰在线小说 | 第一福利在线视频 | 国产精品久久久亚洲 | 成人亚洲精品7777 | 天天视频入口 | 日本高清毛片视频在线看 | 女胁师~牝奴隷调教 | 国产亚洲精品国产第一 |