当前位置:编程学习 > C/C++ >>

c++复习基础要点03 虚析构函数、虚函数表

1.虚析构函数的作用:
  当基类对象指针通过new动态创建一个子类的对象时,通过该指针释放子类对象时,如果基类的析构函数不是虚函数,则释放该对象时只会调用基类的析构函数而不会调用子类析构函数。这样子类释放对象时就无法释放已分配的资源。
如果基类的析构函数为虚函数,则在基类对象指针去释放子类对象时,就会先调用子类的析构函数,在调用基类的析构函数:
 
#include<iostream>
using namespace std;
 
 
class A
{
public:
       virtual  void fun()
       {
              cout<<"thisis virtual for A"<<endl;
       }
       virtual~A()
       {
              cout<<"thisis virtual ~ for A"<<endl;
       }
};
 
class B:public A
{
public:
       voidfun()
       {
              cout<<"thisis virtual for B"<<endl;
       }
 
       virtual~B()
       {
              cout<<"thisis virtual ~ for B"<<endl;
       }
};
 
 
int main()
{
       A*a;
       a=newB;
       a->fun();
       deletea;
       return0;
}
 
结果:
this is virtual for B
this is virtual ~ for B
this is virtual ~ for A
 
当virtual ~A() 去掉virtual时,结果为:
this is virtual for B
this is virtual ~ for A
 
也就是说,类B的析构函数根本就没被调用,一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。
 
所以基类的析构函数应该被定义为虚函数,这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。
 
 当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。
 
2.虚函数表
 
多态性可分为两类:静态多态和动态多态。函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的。
每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说,虚函数表的每一项是一个虚函数的指针。
没有虚函数的C++类,是不会有虚函数表的
 
例子:
class Class1
{
 public:
    m_data1;
    m_data2;
    virtual  vfunc1();
    virtual  vfunc2();
    virtual  vfunc3();
};
 
图示:
 
 
class Class2 : public Class1
{
 public:
    m_data3;
    virtual vfunc2();
 
};
 
图示:
 
虚函数表的指针4个字节大小(vptr),存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。
 
 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,