C++Note 虚析构和纯虚析构

多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码

解决方式:将父类中的析构函数改为虚析构或者纯虚析构

虚析构和纯虚析构共性:

  可以解决父类指针释放子类对象

  都需要有具体的函数实现

虚析构和纯虚析构区别:

  如果是纯虚析构,该类属于抽象类,无法实例化对象

虚析构语法:

virtual ~类名(){}

纯虚析构语法:

virtual ~类名() = 0;//类内纯虚构

类名::类名(){}//作用域 + 类名

虚析构之前:

复制代码
 1 class Animal
 2 {
 3 public:
 4     Animal()
 5     {
 6         cout << "Animal的构造函数调用" << endl;
 7     }
 8     ~Animal()
 9     {
10         cout << "Animal的析构函数调用" << endl;
11     }
12     virtual void speak() = 0;
13 
14 };
15 class Cat :public Animal
16 {
17 public:
18     Cat(string name)
19     {
20         cout << "Cat的构造函数调用" << endl;
21         m_Name = new string(name);
22     }
23     virtual void speak()
24     {
25         cout << *m_Name <<"猫叫" << endl;
26     }
27     ~Cat()
28     {
29         if (m_Name != NULL)
30         {
31             cout << "Cat的析构函数调用" << endl;
32             delete m_Name;
33             m_Name = NULL;
34         }
35     }
36     string* m_Name;
37 };
38 void test()
39 {
40     Animal* animal = new Cat("Tim");
41     animal->speak();
42     //父类指针在析构时候,不会调用子类中析构函数,导致子类如果有堆区属性,出现内存泄露
43     delete animal;
44 }
复制代码

输出:

 虚析构之后:

复制代码
 1 class Animal
 2 {
 3 public:
 4     Animal()
 5     {
 6         cout << "Animal的构造函数调用" << endl;
 7     }
 8     //利用虚析构可以解决 父类指针释放自类对象时不干净的问题
 9     virtual ~Animal()
10     {
11         cout << "Animal的析构函数调用" << endl;
12     }
13     virtual void speak() = 0;
14 };
复制代码

结果输出:

纯虚析构:

复制代码
 1 class Animal
 2 {
 3 public:
 4     Animal()
 5     {
 6         cout << "Animal的构造函数调用" << endl;
 7     }
 8     virtual ~Animal() = 0;//纯虚析构
 9     virtual void speak() = 0;
10 };
复制代码

但是此时报错:无法解析的外部命令( 链接阶段报错)  预处理、编译、汇编、链接

此时纯虚析构只是一个声明,无代码实现,但析构函数有执行,(父类中也可能也有数据开辟到堆区,此时父类中析构函数实现起到作用)

虚析构  或  纯虚析构都需要代码实现

复制代码
 1 class Animal
 2 {
 3 public:
 4     Animal()
 5     {
 6         cout << "Animal的构造函数调用" << endl;
 7     }
 8     virtual ~Animal() = 0;//纯虚析构 需要声明 也需要实现
 9     virtual void speak() = 0;
10 };
11 Animal::~Animal()
12 {
13     cout << "Animal的析构函数调用" << endl;
14 }
复制代码

总结:

  1.虚析构或纯虚析构就是用来解决通过父类指针释放子类对象

  2.如果子类中没有堆区数据,可以不写为虚析构或纯虚析构

  3.拥有纯虚析构函数的类也属于抽象类

posted on   廿陆  阅读(9)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示