為什么析構函數常聲明為虛函數


析構函數的作用與構造函數正好相反,是在對象的生命期結束時,釋放系統為對象所分配的空間,即要撤消一個對象。

用對象指針來調用一個函數,有以下兩種情況:

  1. 如果是虛函數,會調用派生類中的版本。(在有派生類的情況下)

  2. 如果是非虛函數,會調用指針所指類型的實現版本。

析構函數也會遵循以上兩種情況,因為析構函數也是函數嘛,不要把它看得太特殊。 當對象出了作用域或是我們刪除對象指針,析構函數就會被調用。

當派生類對象出了作用域,派生類的析構函數會先調用,然后再調用它父類的析構函數, 這樣能保證分配給對象的內存得到正確釋放。

但是,如果我們刪除一個指向派生類對象的基類指針,而基類析構函數又是非虛的話, 那么就會先調用基類的析構函數(上面第2種情況),派生類的析構函數得不到調用。

 

請看例子:

#include<stdio.h>
#include<iostream>
class A{
public:A();
       virtual~A();
       virtual void fun1(){
           printf("123");
       }
};
A::A(){}
A::~A(){
    printf("Delete class A\n");
}

class B : public A
{
public:B();
       ~B();
       void fun2(){
           printf("123456");
       }
};

B::B(){ }
B::~B(){
    printf("Delete class B\n");
}    

A *a=new B;
//B *b=new A; //無法從“A *”轉換為“B *”

B *c=new B;
A *d=new A;
int main(){


    delete a;
    //delete c;
    //delete d;
    return 0;
}
View Code

析構函數加上虛函數,當你動態申請一個對象時,並且把這個對象的指針賦值給基類,這時當你用這個基類指針釋放內存時,就有用了,因為這樣可以用多態性原理調用對象實際的析構函數來析構內存。

 

#include<stdio.h>
#include<iostream>
class A{
public:A();
       ~A();
       virtual void fun1(){
           printf("123");
       }
};
A::A(){}
A::~A(){
    printf("Delete class A\n");
}

class B : public A
{
public:B();
       ~B();
       void fun2(){
           printf("123456");
       }
};

B::B(){ }
B::~B(){
    printf("Delete class B\n");
}    

A *a=new B;
//B *b=new A; //無法從“A *”轉換為“B *”

B *c=new B;
A *d=new A;
int main(){


    delete a;
    //delete c;
    //delete d;
    return 0;
}
View Code

析構函數去掉虛函數,就不能調用子類中的析構函數了

 

當你動態申請一個對象時,並且把這個對象的指針賦值給當前類,析構函數去掉虛函數,都不會影響子類到父類的虛構

#include<stdio.h>
#include<iostream>
class A{
public:A();
       ~A();
       virtual void fun1(){
           printf("123");
       }
};
A::A(){}
A::~A(){
    printf("Delete class A\n");
}

class B : public A
{
public:B();
       ~B();
       void fun2(){
           printf("123456");
       }
};

B::B(){ }
B::~B(){
    printf("Delete class B\n");
}    

A *a=new B;
//B *b=new A; //無法從“A *”轉換為“B *”

B *c=new B;
A *d=new A;
int main(){


    delete c;
    //delete c;
    //delete d;
    return 0;
}
View Code

 


免責聲明!

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



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