专业编程基础技术教程

网站首页 > 基础教程 正文

C++知识点 50:虚析构和纯虚析构 c++虚函数 析构函数

ccvgpt 2024-11-12 09:54:15 基础教程 301 ℃

50.1 知识点
1.引出

发生多态情况下,如果子类中有在堆区属性,那么不会调用子类的析构函数,
导致子类堆区属性无法被释放

C++知识点 50:虚析构和纯虚析构 c++虚函数 析构函数

2.解决
将父类的析构变为“虚析构”,在父类的析构函数前 + virtual

3.注意: 1) 类内声明,类外实现(实现注意加作用域)
2) 纯虚函数可以没有实现,但纯虚析构必须有实现

50.2 虚析构
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Animal
{
public:
Animal()
{
cout << "Animal默认构造函数调用" << endl;
}
virtual void speak()
{
cout << "动物在说话" << endl;
}

//virtual ~Animal() // 解决没有调用子类析构函数问题
~Animal()
{
cout << "Animal析构函数调用" << endl;
}
};
class Cat :public Animal
{
public:
Cat(char * name) // 有参构造初始化维护的猫的名字
{
cout << "Cat有参构造函数调用" << endl;
this->m_Name = new char[strlen(name) + 1];
strcpy(this->m_Name, name);
}
virtual void speak() {
cout << "小猫"<<this->m_Name<<"在说话" << endl;
}
~Cat() {
if (this->m_Name != NULL) {
cout << "Cat析构函数调用" << endl;
delete[] this->m_Name;
this->m_Name = NULL;
}
}
char * m_Name;
};
void test()
{
Animal *cat = new Cat("Tom");
cat->speak();
delete cat;
}
int main()
{
test();
//结果:
// Animal默认构造函数调用
// Cat有参构造函数调用
// 小猫Tom在说话
// Animal析构函数调用

system("pause");
return EXIT_SUCCESS;
}
现象: Cat析构函数没有被调用
原因: Animal *cat = new Cat("Tom");
虽然new的Cat的指针,但实际上创建的是Animal的指针
因此只调了Animal的析构,没有调用Cat的析构
问题: 多态情况下,如果子类中有在堆区属性,那么不会调用子类的析构函数
导致子类堆区属性无法被释放
解决: 将父类的析构变为“ 虚析构”

50.3 纯虚析构
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<string>
// 简而言之, “ 纯虚析构” 跟“ 虚析构” 基本一样,只是写法不同
class Animal
{
public:
Animal() {
cout << "Animal默认构造函数调用" << endl;
}
// 父类为抽象类,子类中有堆上属性,为了可以让子类的堆上属性释放干净,需要使用虚析构
virtual void speak() = 0;
/*
virtual ~Animal() // 使用虚析构,或者 纯虚析构
{
cout << "Animal析构函数调用" << endl;
}
*/
// 纯虚析构是虚析构的另一种写法
virtual ~Animal() = 0; // 类内声明,类外实现
};
Animal::~Animal() //类外实现需加作用域 //此外区分: 纯虚函数可以没有实现,但纯虚函数必须有实现
{
cout << "Animal析构函数调用" << endl;
}

class Cat:public Animal // 多态条件1
{
public:
Cat(char * name)
{
cout << "Cat默认构造函数调用" << endl;
this->m_Name = new char[strlen(name) + 1];
strcpy(this->m_Name, name);
}
virtual void speak() //多态条件2
{
cout << "小猫"<<this->m_Name<<"在吃饭" << endl;
}

~Cat()
{
cout << "Cat析构函数调用" << endl;
if (this->m_Name != NULL)
{
delete[] this->m_Name;
this->m_Name = NULL;
}
}
char* m_Name;
};
int main()
{
Animal * cat = new Cat("TOM"); // 多态条件3
cat->speak();
delete cat;
system("pause");
return EXIT_SUCCESS;
}


最近发表
标签列表