析构函数声明为虚函数

 
Base *pb;
inherit c;//inherit 是继承 Base的
pb=&c;
delete   pb;时需要调用对象的析构函数,如果基类析构不是virtual型,会根据pb的定义类型调用相应类的析构函数,即调用即类析构,但如果你在派生类析构里有内存释放操作,那就会发生内存泄漏。假如基类析构是virtual型,会根据pb所指对象的类型调用相应类的析构函数,即派生类析构,派生类析构再根据析构函数调用的层次原则调用即类析构。这样就保证不会有问题。 

Effective C++ (第7条:要将多态基类的析构函数声明为虚函数)
这是因为 C++ 做出了这样的规定:当一个派生类对象通过一个指向基类的指针来删除,并且这一基类有一个非虚拟的析构器,此时的结果是不可预知的。通常情况下在运行时,派生类中新派生出的部分得不到销毁。

如果一个类不包含虚函数,通常情况下意味着它将不作为基类使用。当一个类不作为基类时,将它的析构其声明为虚拟的通常情况下不是个好主意
虚函数的实现需要它所在的对象包含额外的信息,这一信息用来在运行时确定本对象需要调用哪个虚函数。通常,这一信息采取一个指针的形式,这个指针被称为“ vptr ”(“虚函数表指针”)。 vptr 指向一个包含函数指针的数组,这一数组称为“ vtbl ”(“虚函数表”),每个包含虚函数的类都有一个与之相关的 vtbl 。当一个虚函数被一个对象调用时,就用到了该对象的 vptr 所指向的 vtbl ,在 vtbl 中查找一个合适的函数指针,然后调用相应的实函数。

需要记住的
应该为多态基类声明虚析构器。一旦一个类包含虚函数,它就应该包含一个虚析构器。
如果一个类不用作基类或者不需具有多态性,便不应该为它声明虚析构器。

一点不明白:为什么基类中析构函数定义为虚函数后,就能执行派生类的析构函数?
我猜测是:因为pb=&c的时候,其派生类的虚拟函数表指针会复制给基类pb,因此会调用其派生类的析构函数,然后再调用基类的析构函数。

需要说明的是,当基类的析构函数被声明为虚函数后,该基类所有的派生类的析构函数不管是否有virtual关键字修饰,都将自动声明为虚函数。

我的理解:有两种情况是要定义虚析构的
1.如果基类中有虚函数,否则如所说,用基类指针去析构派生类,会析构不完全。

2.如果派生类自定义了operator delete()函数,这时不管基类中是否有没有虚函数都要虚析构。否则会用你不希望的方式去析构。

虚函数的内部机制
那么,C++中虚函数为什么可以实现上述的动态联编?实际上,虚函数的内部实现机制本身是比较复杂的,且不同的C++编译器的实现方式又都不一样的。不过,大多数C++编译器采用了VTable结构来实现,VTable称为虚表。
简单地说,当程序编译时,编译就会为虚函数所在的各个类(基类和派生类)各自创建一个VTable,并将类的虚函数放在此表中,然后在其内部创建一个指针vptr指向该虚表结构VTable,vptr称为虚指针。
程序运行时就会根据基类对象所获取的派生类对象将派生类对象的VTable和vptr复制给基类,并由基类来调用,从而实现了类成员函数的动态联编。
可见,动态联编时需要指定派生类对象的地址,因而必须通过基类指针或引用对象才能激活虚函数的动态联编机制。
需要说明的是:派生类中重写的虚函数应与基类的虚函数完全一样,包括虚函数的返回值类型也应一样。在ANSI/ISO C++中,对于一般函数来说,函数返回值类型是不能作为一般函数的重载区分内容;但对于虚函数而言,函数返回值类型不同的虚函数被认为两个不一样的虚函数。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值