虛析構和純虛析構


多態使用時,如果子類有對象開辟到堆區,那么父類指針在釋放時無法調用到子類的析構代碼

解決方式:將父類中的析構函數改為虛析構或者春虛析構

虛析構和純虛析構的共性:

  • 可以解決父類指針釋放子類對象
  • 都需要有具體的函數實現

虛析構和純虛析構的區別:

  • 如果是純虛析構,該類屬於抽象類,無法實例化對象

虛析構語法:

virtual ~類名(){}

純虛析構語法:

virtual ~類名()=0;
類名::類名(){};

 常規操作:

#include<iostream>
using namespace std;
class animal
{
public:
    virtual void speak() = 0;
};


class dog : public animal
{
public:
    void speak()
    {
        cout << "小狗在說話" << endl;
    }
};


class cat : public animal
{
public:
    void speak()
    {
        cout << "小貓在說話" << endl;
    }
};
void test01()
{
    animal* it = new cat;
    it->speak();
    delete it;
}
int main()
{
    test01();
    system("pause");
}

但是如果子類對象有開辟空間到堆區時,在子類中創建指針:

 

class cat : public animal
{
public:
    void speak()
    {
        cout << *m_name<<"小貓在說話" << endl;
    }
    cat(string name) {
        m_name =new string(name);
    }
    string* m_name;
};
void test01()
{
    animal* it = new cat("tom");
    it->speak();
    delete it;
}

在父類子類對象中都打印一些字符會發現,子類的析構函數並沒有調用,說明堆區並沒有釋放干凈,這樣就會造成內存泄露。

這是因為父類指針在析構時並不會調用子類的析構函數,導致子類如果有堆區對象,就會造成內存泄露。

cat類中有堆區屬性,應該在該子類中將其釋放,解決這個問就就需要虛析構

虛析構的語法就是在父類析構函數前加上一個virtual關鍵字,結果:

子類的析構函數已調用。

 以上就是利用父類指針解決子類對象時釋放不干凈的問題

純虛析構

純虛析構需要有什聲明,也需要有具體 的實現;

有了純虛析構后這個類也屬於抽象類,無法實例化對象;

#include<iostream>
#include<string>
using namespace std;
class animal
{
public:
    animal()
    {
        cout << "animal構造函數已調用" << endl;
    }
    //virtual ~animal()  //虛析構    虛析構與純虛析構只能存在一個
    //{
    //    cout << "animal析造函數已調用" << endl;
    //}
    virtual ~animal() = 0; //純虛析構聲明
    virtual void speak() = 0;
};
animal::~animal() //純虛析構具體實現
{
    cout << "animal純虛析構已調用" << endl;
};

class dog : public animal
{
public:
    void speak()
    {
        cout << "小狗在說話" << endl;
    }
};


class cat : public animal
{
public:
    void speak()
    {
        cout << *m_name<<"小貓在說話" << endl;
    }
    cat(string name) {
        cout << "cat構造函數已調用" << endl;
        m_name =new string(name);
    }
    ~cat()
    {
        if (m_name != NULL)
        {
            cout << "cat析構函數已調用" << endl;
            delete m_name;
            m_name = NULL;
        }
    }

    string* m_name;
};
void test01()
{
    animal* it = new cat("tom");
    it->speak();
    delete it;
}
int main()
{
    test01();
    system("pause");
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM