徹底搞懂C++多態虛函數等問題

來源:互聯網
上載者:User

標籤:c++   多態   對象   virtual   虛函數   

1.繼承和覆寫

子類繼承父類,子類可以覆寫基類的函數。當然,直接產生一個子類的對象,用子類的指標操作是沒有問題的。調用的函數是子類的函數,即覆寫後的。

// ConsoleApplication3.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class Base{public:Base(void){cout<<"Base is created"<<endl;}virtual ~Base(void){cout<<"Base destroyed!"<<endl;}void func(){cout<<"Base function is called"<<endl;}};class Demo : public Base{public:Demo(void){cout<<"Demo is created"<<endl;}~Demo(void){cout<<"Demo destroyed!"<<endl;}void func(){cout<<"Demo function is called"<<endl;}};int _tmain(int argc, _TCHAR* argv[]){Demo* demo = new Demo();demo->func();int a;cin>>a;return 0;}


結果:

Base is created
Demo is created
Demo function is called

但是,如果要用父類的指標調用子類的對象呢?還是會調用覆寫後的函數嗎?

答案是不會。。。

// ConsoleApplication3.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class Base{public:Base(void){cout<<"Base is created"<<endl;}virtual ~Base(void){cout<<"Base destroyed!"<<endl;}void func(){cout<<"Base function is called"<<endl;}};class Demo : public Base{public:Demo(void){cout<<"Demo is created"<<endl;}~Demo(void){cout<<"Demo destroyed!"<<endl;}void func(){cout<<"Demo function is called"<<endl;}};int _tmain(int argc, _TCHAR* argv[]){Base* base = new Demo();base->func();//Demo* demo = new Demo();//demo->func();//delete base;int a;cin>>a;return 0;}


Base is created
Demo is created
Base function is called

那麼要腫麼辦呢?

下面就是多態的方法啦。

2.關於多態

多態實際上就是用基類的指標來操作子類的對象。但是上面覆寫了之後,卻調用的還是父類的函數。要解決這個問題就要加一個關鍵字,virtual。

就是這一個關鍵字就改變了程式啟動並執行結果。

// ConsoleApplication3.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class Base{public:Base(void){cout<<"Base is created"<<endl;}virtual ~Base(void){cout<<"Base destroyed!"<<endl;}void virtual func(){cout<<"Base function is called"<<endl;}};class Demo : public Base{public:Demo(void){cout<<"Demo is created"<<endl;}~Demo(void){cout<<"Demo destroyed!"<<endl;}void func(){cout<<"Demo function is called"<<endl;}};int _tmain(int argc, _TCHAR* argv[]){Base* base = new Demo();base->func();//Demo* demo = new Demo();//demo->func();//delete base;int a;cin>>a;return 0;}

在要被覆寫的基類函數前面加上virtual關鍵字就可以使父類指標調用子類對象的重寫的函數。

結果:

Base is created
Demo is created
Demo function is called


但是還有一種情況,就是即使覆寫了父類的函數,但仍然需要父類的函數的功能,這要腫麼辦呢?

最開始我的想法是從父類的Ctrl+c 然後Ctrl+v過來。後來一想,這個也忒麻煩了吧,而且不利於代碼的維護。還好,有這樣一個簡單的方法。


在子類覆寫的函數中,加上這句

Base::func();

即調用了父類的函數,然後再加上子類特有的功能即可。



// ConsoleApplication3.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class Base{public:Base(void){cout<<"Base is created"<<endl;}virtual ~Base(void){cout<<"Base destroyed!"<<endl;}void virtual func(){cout<<"Base function is called"<<endl;}};class Demo : public Base{public:Demo(void){cout<<"Demo is created"<<endl;}~Demo(void){cout<<"Demo destroyed!"<<endl;}void func(){Base::func();cout<<"Demo function is called"<<endl;}};int _tmain(int argc, _TCHAR* argv[]){Base* base = new Demo();base->func();//Demo* demo = new Demo();//demo->func();//delete base;int a;cin>>a;return 0;}

Base is created
Demo is created
Base function is called
Demo function is called

這樣就能既使用子類的特有功能,又調用了父類的功能。


3..虛解構函式

如果是基類,沒有定義為虛解構函式的話,用基類指標操作子類,不會調用子類對象的解構函式,會導致只釋放了基類部分的資源,而定義在子類部分的資源沒被釋放,造成記憶體泄露。

// ConsoleApplication3.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class Base{public:Base(void){cout<<"Base is created"<<endl;}virtual ~Base(void){cout<<"Base destroyed!"<<endl;}};class Demo : public Base{public:Demo(void){cout<<"Demo is created"<<endl;}~Demo(void){cout<<"Demo destroyed!"<<endl;}};int _tmain(int argc, _TCHAR* argv[]){Base* base = new Demo();delete base;int a;cin>>a;return 0;}
運行結果:

Base is created
Demo is created
Demo destroyed!
Base destroyed!

子類物件建構時,會先調用父類的建構函式,然後調用子類的建構函式,初始化子類的特有部分。析構時,順序相反,先調用子類的解構函式,再調用父類的解構函式。

建構函式和解構函式中都是預設調用父類的函數的。不用像上面那樣要額外加上調用父類函數的句子。




徹底搞懂C++多態虛函數等問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.