您的位置:首页 > 编程语言 > C语言/C++

C++基础---虚析构函数与纯虚析构函数

2015-09-04 16:20 323 查看

1. 虚析构函数与纯虚析构函数

1.1 虚析构函数与纯虚析构函数的定义

虚析构函数:为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象;

虚析构函数:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数,无故的声明虚析构函数和永远不去声明一样是错误的;

class <类名>
{
virtual ~<类名>();
…
};
即:virtual ~A();


纯虚析构函数:抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单,在想要成为抽象类的类里声明一个纯虚析构函数;

class <类名>
{
virtual ~<类名>() = 0;
…
};
即:virtual ~A() = 0;


注:如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。

1.2 带有虚函数功能的类需要一个虚析构函数的原因

如果一个类有虚函数功能,它经常作为一个基类使用;

如果它是一个基类,它的派生类经常使用new来分配;

如果一个派生类对象使用new来分配,并且通过一个指向它的基类的指针来控制,那么它经常通过一个指向它的基类的指针来删除它;

注:

(1)如果基类没有虚析构函数,结果将是不确定的,实际发生时,派生类的析构函数永远不会被调用。

(2)如果基类有虚析构函数的话,最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。

1.3 虚析构函数的注意点

由于析构函数不允许有参数,因此它不可能实现重载,那么一个类就只能有一个虚析构函数;

只要基类的析构函数被声明为虚函数,则派生类的析构函数无论说明与否,都自然是析构函数;

如果基类中定义了虚函数,析构函数也应说明为虚函数,这样对内存的回收更准确些;

注:在C++中虚构造函数是不存在的,因此也无法声明。

1.4 虚析构函数的实例

(1)在带有虚函数的基类中定义普通析构函数

#include <iostream>

using namespace std;

class A
{
public:
A(){cout<<"A()..."<<endl;}
~A(){cout<<"~A()..."<<endl;}

public:
virtual void func1()
{
cout<<"A::func1()"<<endl;
}
};

class B : public A
{
public:
B(){cout<<"B()..."<<endl;}
~B(){cout<<"~B()..."<<endl;}

public:
virtual void func1()
{
cout<<"B::func1()"<<endl;
}
};

int main()
{
A *pb = new B;
pb->func1();
delete pb;

system("pause");
return 0;
}
=>A()...
B()...
B::func1()
~A()...
注:派生类继承自基类,那么基类就只会存在于派生类中,直到派生类调用析构函数后。
当上述这种情况,基类的析构函数调用比派生类要早,会造成的一种情况就是类成员不存在了,而类本身却还在,但是类存在的情况下,类成员应该还存在。所以这就矛盾了,应该派生类的析构函数会先被调用,基类的析构函数再被调用。


(2)在带有虚函数的基类中定义虚析构函数

#include <iostream>

using namespace std;

class A
{
public:
A(){cout<<"A()..."<<endl;}
virtual ~A(){cout<<"virtual ~A()..."<<endl;}

public:
virtual void func1()
{
cout<<"A::func1()"<<endl;
}
};

class B : public A
{
public:
B(){cout<<"B()..."<<endl;}
virtual ~B(){cout<<"virtual ~B()..."<<endl;}

public:
virtual void func1()
{
cout<<"B::func1()"<<endl;
}
};

int main()
{
A *pb = new B;
pb->func1();
delete pb;

system("pause");
return 0;
}
=>A()...
B()...
B::func1()
virtual ~B()...
virtual ~A()...


注:析构函数的作用并不是删除对象,而是撤销对象占用内存之前完成的一些清理工作。

(1)抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以在想要成为抽象类的类里声明一个纯虚析构函数。

(2)定义一个函数为虚函数,不代表该函数未被实现,只是为了来实现多态。

(3)定义一个函数为纯虚函数,才表示函数未被实现 ,定义它是为了实现一个接口,起一个规范作用。继承抽象类的派生类要实现这个函数。

参考文献:

[1]《C++全方位学习》范磊——第十三章

[2]《C++程序设计教程(第二版)》钱能——第五章、第六章、第七章

[3]《C++ Primer(第5版)》王刚 杨巨峰——第一章、第六章

[4] 百度搜索关键字:C++函数、虚析构函数、纯虚析构函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: