首页 百科知识 ++虚析构函数

++虚析构函数

时间:2022-09-22 百科知识 版权反馈
【摘要】:析构函数则用于销毁对象时完成相应的资源释放工作,析构函数可以被声明为虚函数。例1:在本类中定义了两个类,一个基类,一个派生类,派生类和基类中都分别定义了自己的构造函数和析构函数。这串字符,同样地派生类的构造函数也被调用了。字符串,这说明基类的析构函数被调用了,a指针所指向的10个整型内存空间被释放了。

在类中,构造函数用于初始化对象及相关操作,构造函数是不能声明为虚函数的,因为在执行构造函数前对象尚未完成创建,虚函数表尚不存在,此时就无法去查询虚函数表,因此也就无法得知该调用哪一个构造函数了。

析构函数则用于销毁对象时完成相应的资源释放工作,析构函数可以被声明为虚函数。我们先通过一个例子来说明析构函数声明为虚函数的必要性。

例1:

#include<iostream>

using namespace std;


class base

{

public:

    base();

    ~base();

private:

    int * a;

};


class derived: public base

{

public:

    derived();

    ~derived();

private:

    int * b;

};


base::base()

{

    cout<<"base constructor!"<<endl;

    a = new int[10];

}


base::~base()

{

    cout<<"base destructor!"<<endl;

    delete[] a;

}


derived::derived()

{

    cout<<"derived constructor!"<<endl;

    b = new int[1000];

}


derived::~derived()

{

    cout<<"derived destructor!"<<endl;

    delete[] b;

}


int main()

{

    base* p;

    p = new derived;

    delete p;

    return 0;

}

在本类中定义了两个类,一个基类,一个派生类,派生类和基类中都分别定义了自己的构造函数和析构函数。基类和派生类中各有一个int型指针成员变量,在基类的构造函数中,给指针变量a分配了10个int型空间,在基类的析构函数则用于将是将a所指向的空间释放掉,在派生类的构造函数中,指针成员变量被分配了1000个整型空间,派生类的析构函数则是为了释放掉b指针所指向的存储空间。在主函数中,我们创建一个基类类型的指针,指针指向一个派生类对象,之后释放p指针所指向的对象的存储空间。最后程序运行结果如下:
    base constructor!
    derived constructor!
    base destructor!

观察程序运行结果,程序打印出了“base constructor!”这串字符,则说明基类的构造函数被调用了,之后又打印出了“derived constructor!”这串字符,同样地派生类的构造函数也被调用了。当我们用new操作符创建一个派生类对象时会先调用基类构造函数,然后再调用派生类构造函数,程序输出结果与我们料想的是一致的。至此基类的成员变量a通过构造函数被分配了10个整型存储空间,派生类的成员变量b通过构造函数被分配了1000个整型存储空间。之后程序打印出了“base destructor!”字符串,这说明基类的析构函数被调用了,a指针所指向的10个整型内存空间被释放了。但是之后却并未调用派生类的析构函数,不调用派生类的析构函数则会导致b指针所指向的1000个整型存储空间不会被释放,如此一来造成了内存泄露了。内存泄露问题肯定是我们程序设计人员需要极力避免的。本例中出现的问题就是因为派生类的析构函数未被调用,为了解决这个问题,我们将基类的析构函数声明为虚函数,修改后基类的定义如下:

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈