關於C++虛函數,純虛函數以及模板等重要概念的深刻討論(二)

2.析構與虛析構函數java

  爲了說明基類的析構函數必須爲虛析構函數,咱們來實踐一下:在A的析構函數中加入輸出cout << "This is A class." << endl;同理在B的析構函數中也加入輸出cout << "This is B class." << endl;ios

最後在main函數objectC->print();下方加入語句:delete objectC; objectC = NULL;從而銷燬對象,調用析構函數。若是基類A的析構函數非虛析構的話,運行結果以下:設計模式

        

若是將基類A的析構函數改寫爲虛析構函數:virtual ~A();那麼運行的結果以下:app

        

    能夠清晰的看到,在基類A中若是是非虛析構函數時,銷燬objectC 對象的時候則沒有調用B析構函數,而若爲虛析構函數的話,就會調用B的析構函數。所以爲了防止釋放指向子類的基類指針時,子類發生內存泄露現象,咱們必須將基類的析構函數設置爲虛析構!函數

3.虛函數與純虛函數spa

    虛函數便是在聲明函數的時候在前面加入virtual 關鍵字如:virtual void print(); 而純虛函數則是這樣定義的:virtual void print() = 0; 即純虛函數沒有實體,實體是須要它的繼承重寫來實現的。咱們來看一段實例代碼:設計

// Test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream"
using namespace std;

class C
{
	virtual void draw1(){};
	virtual void draw2() = 0;
};
class A
{
private:
	int valueA;
public:
	A();
	A(int value);
	virtual ~A();
	virtual void print(int value);
};
//The class A realize.
A::A()
{
	valueA = 0;
}
A::A(int value)
{
	valueA = value;
}
A::~A()
{
	cout << "This is A class." << endl;
}
void A::print(int value)
{
	cout << "This is A print and Value is :" << value <<endl;
}

class B:public A, public C
{
private:
	int valueB;
public:
	B();
	B(int value);
	~B();
        void print(int value);
	void draw2();
};
//The class B realize.
B::B()
{
	valueB = 0;
}
B::B(int value):A(value)
{
	valueB = value;
}
B::~B()
{
	cout << "This is B class." << endl;
}
void B::print(int value)
{
	cout << "This is B print and Value is :" << value << endl;
}
void B::draw2()
{
	cout << "This is B draw and Value is :" << valueB << endl;
}
int main(void)
{
	A *objectA = new A(10);
	B *objectB = new B(20);
	A *objectC = objectB;

	objectA->print(1);
	objectB->print(2);
	objectC->print(3);
	delete objectC;
	objectC = NULL;
	return 0;
}

在上述的代碼中咱們新加入了一個類C,它裏面包含了一個虛函數draw1,以及一個純虛函數draw2;而後咱們讓B繼承這個類,而且在B類中咱們重寫了draw2函數,若是不重寫那麼會出現如下錯誤:指針

        

    編譯器告訴咱們必需要重寫draw2函數,這樣程序就能順利的運行了;咱們把帶有虛函數的類稱爲抽象類,即上述實例中C就爲抽象類,抽象類的特色是:它沒有實體,咱們不能把抽象類給實例化,即不能定義一個抽象類的對象;感興趣的同窗能夠試一下,編譯器會報錯的不能實例化抽象類。code

    既然抽象類不能被實例化,並且他的純虛成員函數還必須被繼承它的子類繼承,那麼這種結構有什麼用呢?答案是,它能夠實現很好的擴展,在大型軟件的編寫過程當中抽象類和純虛函數會常常的用到,若是你看設計模式的話,能夠看到有不少的設計模式中會用到抽象類和純虛函數,它能夠實現一種接口的做用,其實若是抽象類中只有純虛函數這一種結構,那麼它跟C#以及java等語言中的接口(也有人叫協議)的概念是同樣的,最新式的用於Iphone開發的Swift語言就大量的使用接口,因此人們習慣叫這種新式的語言爲面向協議的語言。可見抽象類和純虛函數是有多麼的強大。建議你們如何對它們感興趣的話,必定要看看設計模式,你會有很大的收穫!對象

 

<未完待續>

相關文章
相關標籤/搜索