当前位置:网站首页>虚析构和纯虚析构
虚析构和纯虚析构
2022-06-30 05:05:00 【叫我小秦就好了】
导言
本文将介绍为什么要将多态性质基类的析构函数声明为虚函数,以及什么是纯虚析构函数。

virtual 析构函数
资源泄漏出现
有时我们希望借助父类指针释放子类对象::
class Person
{
public:
Person();
~Person();
...
};
class Student : public Person
{
... };
// 我们用基类指针指向派生类对象并释放
Person* ptr = new Student;
...
delete ptr;
C++明确指出,当派生类对象经由一个基类指针删除,而该基类的析构函数并不是虚函数,其结果是未定义的。
- 实际执行时通常发生的是对象的派生成分没被销毁
- 也就是说声明于
Student类内的成员变量没被销毁 - 然而其基类成分会被销毁,于是造成了诡异的资源泄漏
解决
解决这个问题的方法很简单,只需要将基类的析构函数声明为虚函数即可。这样delete基类指针时,会销毁整个对象,包括所有的派生成分。
虚函数:即被
virtual修饰的类成员函数称为虚函数。
class Person
{
public:
Person();
virtual ~Person();
...
};
class Student : public Person
{
... };
Person* ptr = new Student;
...
delete ptr;
此时,当调用析构函数时,首先会找到对象内的虚表指针,在虚表指针所指向的虚表中找到适当的函数指针并调用。
总结:
- 带多态性质的基类应该声明一个
virtual析构函数。如果基类带有任何virtual函数,它就应该拥有一个virtual析构函数 - 类的设计目的如果不是作为基类使用,或不是为了具备多态性,就不该声明为
virtual析构函数
pure virtual析构函数
在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。
常规纯虚函数
因为包含纯虚函数的类不能实例化出对象,所以纯虚函数一般没有函数体。
- 没有对象无法调用该纯虚函数,因此实现没有价值,通常不实现
或许你会想到用类类型的指针来调用,下面就来看一下这种方法:
class Animal
{
public:
virtual void Run() = 0;
void Fly();
};
void Animal::Run() {
cout << "Run()" << endl; }
void Animal::Fly() {
cout << "Fly()" << endl; }
Animal* ptr = nullptr;
ptr->Fly(); // 程序正常屏幕打印Fly()
ptr->Run(); // 程序崩溃屏幕不打印
为什么会出现上面的情况?普通函数和纯虚函数有什么不同吗?
这是因为虚函数的调用需要通过虚表指针,没有对象也就没有虚表指针,故上述代码会崩溃。
纯虚析构
有时我们需要一个抽象类,但又没有纯虚函数,该怎么办呢?由于抽象类总是被当作基类来使用,而基类又应该有个virtual 析构函数,并且由于纯虚函数会产生抽象类,因此我们可以:把希望成为抽象的那个类声明一个pure virtual 析构函数。
class Animal
{
public:
virtual ~Animal() = 0;
};
// 必须为这个pure virtual函数提供一份定义,否则连接器会报错
Animal::~Animal() {
}
析构函数的运行逻辑是,最深层派生的呢个类其析构函数最先被调用,然后是其每一个基类的析构函数被调用。编译器会在Animal的派生类的析构函数中创建一个对~Animal的调用动作,所以必须为这个函数提供一份定义。否则,连接器会报错。
边栏推荐
- Writing unityshader with sublimetext
- Pycharm database tool
- Unity application class and data file path
- Unreal 4 learning notes - data storage using blueprints
- Force buckle 704 Binary search
- Tensorflow2 of ubantu18.04 X installation
- Solution to 293 problems in the week of Li Kou
- Unity ontriggerenter does not call
- 【VCS+Verdi聯合仿真】~ 以計數器為例
- Unity + hololens common basic functions
猜你喜欢

On mask culling of unity

Yolov5 torch installation

Some problems encountered in unity steamvr

Solution to Autowired annotation warning

Unity script life cycle and execution sequence

中文版PyCharm改为英文版PyCharm

Approaching history, introduction to the London Guard Museum

harbor api 2.0查询

Force buckle 59 Spiral matrix II

redis集群概念
随机推荐
Initial environment configuration of the list of OpenGL super classic (version 7) vs2019
How to install win7 on AMD Ruilong CPU A320 series motherboard
Oracle-数据的基本操作
Chapter 10 of OpenGL super classic (7th Edition) calculation shader
Harbor API 2.0 query
Unity a* road finding force planning
PBR material: basic principle and simple fabrication
Log writing specification
2021-03-16
Moore Manor diary I: realize the reclamation, sowing, watering and harvest in Moore Manor
力扣977. 有序数组的平方
Tcp/ip protocol details Volume I (Reading Guide)
Sailing experience not to be missed in New York Tourism: take you to enjoy the magnificent city scenery from different perspectives
很紧张,第一天做软件测试,需要做什么?
Records of problems encountered in unity + hololens development
Unity Logitech steering wheel access
Pycharm database tool
Create transfer generation point
2021-06-17 solve the problem of QML borderless window stretching, window jitter and flicker when stretching and shrinking
MySQL query gadget (I) replace a property value of the object in the JSON array in the JSON format string field