網(wǎng)站服務器租用多少錢一年合適濟南網(wǎng)站設計
純虛析構(gòu)的問題
多態(tài)使用時,如果子類中有屬性開辟到堆區(qū),那么父類指針在釋放時無法調(diào)用到子類的析構(gòu)代碼。
解決方式:將父類中的析構(gòu)函數(shù)改為虛析構(gòu)或者純虛析構(gòu)
虛析構(gòu)和純虛析構(gòu)共性:
- 可以解決父類指針釋放子類對象
- 都需要有具體的函數(shù)實現(xiàn)
虛析構(gòu)和純虛析構(gòu)區(qū)別:
- 如果是純虛析構(gòu),該類屬于抽象類,無法實例化對象
虛析構(gòu)語法:
virtual ~類名(){}
純虛析構(gòu)語法:
virtual ~類名() = 0;
類名::~類名(){}
示例:
class Animal {
public:Animal(){cout << "Animal 構(gòu)造函數(shù)調(diào)用!" << endl;}virtual void Speak() = 0;//析構(gòu)函數(shù)加上virtual關鍵字,變成虛析構(gòu)函數(shù)//virtual ~Animal()//{// cout << "Animal虛析構(gòu)函數(shù)調(diào)用!" << endl;//}virtual ~Animal() = 0;
};Animal::~Animal()
{cout << "Animal 純虛析構(gòu)函數(shù)調(diào)用!" << endl;
}//和包含普通純虛函數(shù)的類一樣,包含了純虛析構(gòu)函數(shù)的類也是一個抽象類。不能夠被實例化。class Cat : public Animal {
public:Cat(string name){cout << "Cat構(gòu)造函數(shù)調(diào)用!" << endl;m_Name = new string(name);}virtual void Speak(){cout << *m_Name << "小貓在說話!" << endl;}~Cat(){cout << "Cat析構(gòu)函數(shù)調(diào)用!" << endl;if (this->m_Name != NULL) {delete m_Name;m_Name = NULL;}}public:string *m_Name;
};void test01()
{Animal *animal = new Cat("Tom");animal->Speak();//通過父類指針去釋放,會導致子類對象可能清理不干凈,造成內(nèi)存泄漏//怎么解決?給基類增加一個虛析構(gòu)函數(shù)//虛析構(gòu)函數(shù)就是用來解決通過父類指針釋放子類對象delete animal;
}int main() {test01();system("pause");return 0;
}
注意:即使是純虛析構(gòu)也需要有具體的實現(xiàn)。因為包含純虛函數(shù)的類為抽象類,被繼承后,在派生類析構(gòu)函數(shù)被調(diào)用時抽象類析構(gòu)函數(shù)也將被調(diào)用,因此必須有實現(xiàn)。唯一麻煩就是必須在類的定義之外(cpp文件)實現(xiàn)它。
總結(jié):
? 1. 虛析構(gòu)或純虛析構(gòu)就是用來解決通過父類指針釋放子類對象
? 2. 如果子類中沒有堆區(qū)數(shù)據(jù),可以不寫為虛析構(gòu)或純虛析構(gòu)
? 3. 擁有純虛析構(gòu)函數(shù)的類也屬于抽象類
純虛函數(shù)的實現(xiàn)案例:純虛析構(gòu)函數(shù)必須有實現(xiàn)
純虛函數(shù)可以有實現(xiàn):唯一麻煩就是必須在類的定義之外(cpp文件)實現(xiàn)它。
申明一個函數(shù)為純虛并不意味著它沒有實現(xiàn),它意味著:
- 當前類是抽象類 ;
- 任何從此類派生的實體類必須將此函數(shù)申明為一個“普通”的虛函數(shù)(也就是說,
不能帶“= 0”)。
1、純虛函數(shù)例子:
聲明一個pure virtual
函數(shù)的目的是為了讓 derived classes
只繼承函數(shù)接口,派生類必須提供實現(xiàn)。
可以為pure virtual
函數(shù)提供實現(xiàn),但使用時需要指明所屬類,如:
//.h
class A{
public:virtual void func1() = 0;
};
class B : public A{
public:virtual void func1(){A::func1();};
};//.cpp
void A::func1(){..........}B b;
b.A::func1(); // 與b.func1()結(jié)果相同,相當于提供了缺省實現(xiàn),但派生類需要主動指定。
2、純虛析構(gòu)函數(shù)必須有實現(xiàn):
因為包含純虛函數(shù)的類為抽象類,被繼承后,在派生類析構(gòu)函數(shù)被調(diào)用時抽象類析構(gòu)函數(shù)也將被調(diào)用,因此必須有實現(xiàn)。
class A{
public:virtual ~A() = 0;
};//.cpp
A::~A(){...}
總結(jié):
1、純虛函數(shù)可以有實現(xiàn),但必須在類的定義之外(cpp文件)實現(xiàn)。
2、純虛析構(gòu)函數(shù)必須有實現(xiàn)。
參考鏈接:
純虛函數(shù)的實現(xiàn)案例:純虛析構(gòu)函數(shù)必須有實現(xiàn)