C++ 遗失的子类析构函数

这篇博文所讲的是多态中的一个小BUG

我们知道,在构造函数中调用了new给指针分配内存,那么就要在析构函数中释放掉该内存;那么,如果在多态实验中 基类指针指向子类对象时会怎么样呢?

代码:

#include <iostream>
#include <string.h>

class Father {
public:
	Father(const char *addr = "中国") {
		std::cout << "调用了Father类的构造函数" << std::endl;
		this->addr = new char[strlen(addr)+1];
		strcpy_s(this->addr, strlen(addr)+1, addr);
	}

	~Father() {
		std::cout << "调用了Fahter类的析构函数" << std::endl;
		if (addr) {
			delete addr;
			addr = NULL;
		}
	}

private:
	char *addr;
};

class Son : public Father {
public:
	Son(const char *game = "吃鸡", const char *addr = "中国") : Father(addr) {
		std::cout << "调用了Son类的构造函数" << std::endl;
		this->game = new char[strlen(game)+1];
		strcpy_s(this->game, strlen(game)+1, game);
	}

	~Son() {
		std::cout << "调用了Son类的析构函数" << std::endl;
		if (game) {
			delete game;
			game = NULL;
		}
	}

private:
	char *game;
};
int main(void) {
	std::cout << "---示例一---" << std::endl;
	Father *father = new Father();
	delete father;

	std::cout << "---示例二---" << std::endl;
	Son *son = new Son();
	delete son;

	std::cout << "---示例三---" << std::endl;
	father = new Son();
	delete father;

	system("pause");
	return 0;
}

运行截图:

在这里插入图片描述

在示例三中,竟然没有调用Son类的析构函数来释放内存,为什么会这样呢?

解决方案:

在基类的析构函数前加上 virtual 关键字

// 把Father类的析构函数定义为virtual函数时,
// 如果对 Father类的指针使用delete操作时,
// 就会对该指针使用“动态析构”:
// 如果这个指针,指向的是子类对象,
// 那么会先调用该子类的析构函数,再调用自己类的析构函数

virtual ~Father() {
		std::cout << "调用了Fahter类的析构函数" << std::endl;
		if (addr) {
			delete addr;
			addr = NULL;
		}
	}

运行截图:

在这里插入图片描述

【注意】
为了防止内存泄露,最好是在基类析构函数上添加virtual关键字,使基类析构函数为虚函数
目的在于,当使用delete释放基类指针时,会实现动态的析构:
1.如果基类指针指向的是基类对象,那么只调用基类的析构函数;
2.如果基类指针指向的是子类对象,那么先调用子类的析构函数,再调用父类的析构函数。


可别小看那一点点的内存就不要释放掉,积累成多,这个道理应该要懂得!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值