网站首页 > 基础教程 正文
50.1 知识点
1.引出
发生多态情况下,如果子类中有在堆区属性,那么不会调用子类的析构函数,
导致子类堆区属性无法被释放
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;
}
猜你喜欢
- 2024-11-12 金三银四不跳槽更待何时?安卓开发1年字节5面面经,已成功上岸
- 2024-11-12 C++要学到什么程度才能找到实习? c++学完学什么
- 2024-11-12 C++基础语法梳理:inline 内联函数!虚函数可以是内联函数吗?
- 2024-11-12 C++基类中虚析构函数 c++ 虚析构函数
- 2024-11-12 C和C++代码精粹:C语言和C++有什么区别么?
- 2024-11-12 3个面试C++开发岗位的高频笔试题 c++软件开发面试
- 2024-11-12 一文在手,"类间关系"不再困惑
- 2024-11-12 c++的面试总结 c++面试知识点
- 2024-11-12 C++ 虚函数 实例学习 简单易懂 c++虚函数的使用
- 2024-11-12 C++里面的虚析构函数 虚构造函数与虚析构函数
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)