为什么析构函数常声明为虚函数

转自  http://www.cnblogs.com/huhuuu/archive/2013/12/01/3453063.html

析构函数的作用与构造函数正好相反,是在对象的生命期结束时,释放系统为对象所分配的空间,即要撤消一个对象。

用对象指针来调用一个函数,有以下两种情况:
1.如果是虚函数,会调用派生类中的版本。(在有派生类的情况下)
2.如果是非虚函数,会调用指针所指类型的实现版本。

析构函数也会遵循以上两种情况,因为析构函数也是函数嘛,不要把它看得太特殊。 当对象出了作用域或是我们删除对象指针,析构函数就会被调用。
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;
}

析构函数加上虚函数,当你动态申请一个对象时,并且把这个对象的指针赋值给基类,这时当你用这个基类指针释放内存时,就有用了,因为这样可以用多态性原理调用对象实际的析构函数来析构内存。

#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;
}

析构函数去掉虚函数,就不能调用子类中的析构函数了

当你动态申请一个对象时,并且把这个对象的指针赋值给当前类,析构函数去掉虚函数,都不会影响子类到父类的虚构

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值