C++ 基础【15】

本文代码仓库地址: gitee码云CSDN笔记仓库地址



虚析构函数和纯虚析构函数【Class31】

// 多态 -- 虚析构函数和纯虚析构函数
/*
* 语法:
* 虚析构函数语法:
* virtual ~类名(){}
* 纯虚析构函数语法:
* virtual ~类名() = 0;
* 纯虚析构函数需要类外实现
* 类名::~类名(){}
* 
* 虚析构函数和纯虚析构函数共性:
* 1、可以解决父类指针释放子类对象
* 2、都需要具有具体函数实现
* 
* 虚析构函数和纯虚析构函数区别:如果是纯虚析构函数,该类属于抽象类,无法实例化对象
* 
* 总结:
* 1、虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
* 2、如果子类中没有堆区数据,可以不用写虚析构函数或纯虚析构函数
* 3、拥有纯虚析构函数的类也属于抽象类【只有虚析构函数的类不属于抽象类】
*/
#include <iostream>

using namespace std;

// 一般类 -- 父类
class mClass01_xy {
public:
	mClass01_xy() {
		cout << "父类 mClass01_xy 中的构造函数" << endl;
	}

	~mClass01_xy() {
		cout << "父类 mClass01_xy 中的析构函数函数" << endl;
	}
	
};

// 继承一般父类 -- 子类
class mClass0101_xy :public mClass01_xy{
public:
	string* mName;

	mClass0101_xy(string name) {
		mName = new string(name);
		cout << "子类 mClass0101_xy 中的构造函数 -- " << *mName << endl;
	}

	~mClass0101_xy() {
		cout << "子类 mClass0101_xy 中的析构函数函数 -- " << *mName << endl;
		if (mName != NULL)
		{
			delete mName;
			mName = NULL;
		}
	}

};

// 验证 无虚析构函数的时候不能释放子类的析构函数
void fun01() {
	// 父类可以实例化,其不属于抽象类
	mClass01_xy* mc = new mClass01_xy;
	delete mc;
	cout << endl;

	// 声明会调用父类和子类中的构造函数
	mClass01_xy* mc1 = new mClass0101_xy("小印01");
	// 这里释放的时候只能调用父类中的析构函数,子类的中无法调用
	if (mc1 != NULL)
	{
		delete mc1;
		mc1 = NULL;
	}
}

// =========================================================================

// 带有虚析构函数 -- 父类
class mClass02_xy {
public:
	mClass02_xy() {
		cout << "父类 mClass02_xy 中的构造函数" << endl;
	}

	virtual ~mClass02_xy() {
		cout << "父类 mClass02_xy 中的析构函数函数" << endl;
	}

};

// 继承带有虚析构函数父类 -- 子类
class mClass0201_xy :public mClass02_xy{
public:
	string* mName;

	mClass0201_xy(string name) {
		mName = new string(name);
		cout << "子类 mClass0201_xy 中的构造函数 -- " << *mName << endl;
	}

	virtual ~mClass0201_xy() {
		cout << "子类 mClass0201_xy 中的析构函数函数 -- " << *mName << endl;
		if (mName != NULL)
		{
			delete mName;
			mName = NULL;
		}
	}

};

// 验证 带有虚析构函数的时候释放是否会调用子类中的析构函数
void fun02() {
	// 父类可以实例化,其不属于抽象类
	mClass02_xy* mc = new mClass02_xy;
	delete mc;
	cout << endl;

	// 声明会调用父类和子类中的构造函数
	mClass02_xy* mc1 = new mClass0201_xy("小印02");
	// 这里释放的时候父类和子类中的析构函数都会被调用
	if (mc1 != NULL)
	{
		delete mc1;
		mc1 = NULL;
	}
}

// =========================================================================

// 带有纯虚析构函数 -- 父类
class mClass03_xy {
public:
	mClass03_xy() {
		cout << "父类 mClass03_xy 中的构造函数" << endl;
	}

	virtual ~mClass03_xy() = 0;

};

// 类外实现
mClass03_xy::~mClass03_xy() {
	cout << "父类 mClass03_xy 中的析构函数函数" << endl;
}

// 继承带有纯虚析构函数父类 -- 子类
class mClass0301_xy :public mClass03_xy {
public:
	string* mName;

	mClass0301_xy(string name) {
		mName = new string(name);
		cout << "子类 mClass0301_xy 中的构造函数 -- " << *mName << endl;
	}

	virtual ~mClass0301_xy() {
		cout << "子类 mClass0301_xy 中的析构函数函数 -- " << *mName << endl;
		if (mName != NULL)
		{
			delete mName;
			mName = NULL;
		}
	}

};

// 验证 带有纯虚析构函数的时候释放是否会调用子类中的析构函数
void fun03() {
	// 父类不可以实例化,其属于抽象类
	/* mClass03_xy* mc = new mClass03_xy;
	   delete mc;
	   cout << endl; */

	// 声明会调用父类和子类中的构造函数
	mClass03_xy* mc1 = new mClass0301_xy("小印03");
	// 这里释放的时候父类和子类中的析构函数都会被调用
	if (mc1 != NULL)
	{
		delete mc1;
		mc1 = NULL;
	}
}


int main() {

	fun01();
	cout << "------------------分界线------------------" << endl;
	fun02();
	cout << "------------------分界线------------------" << endl;
	fun03();

	cout << endl;
	system("pause");
	return 0;
}

案例3:采购小能手【Class32】

// 多态 -- 案例3:采购小能手
/*
* 思路:
* 1、创建好各种菜的父类,比如:土豆
* 2、创建子类各个商家对应好每种菜,需要传进来商家,以及获取父类中的菜品名
* 3、需要采购那些菜,要给出需要那些菜,我这里写死的,使用多态,父类指针指向子类,子类的构造需要传过去商家,然后调用子类重写父类中的函数,打印采购信息
* 4、释放在堆区开辟的内存,子类中开辟的在其析构函数中释放,这里就需要Class31中的知识
*/
#include <iostream>

using namespace std;

// 土豆 -- 父类
class mClass01_xy {
public:
	string* mPotato;

	mClass01_xy() {
		mPotato = new string("土豆");
		cout << "------ mClass01_xy 的构造函数" << endl;
	}

	// 纯虚函数【会让类变成抽象类,类不可实例化】
	virtual void mFun01() = 0;

	// 虚析构函数【不会让类称为抽象类,类可以实例化】
	virtual ~mClass01_xy() {
		if (mPotato != NULL)
		{
			delete mPotato;
			mPotato = NULL;
		}
		cout << "------ mClass01_xy 的析构函数" << endl;
	}

};

// 青椒 -- 父类
class mClass02_xy {
public:
	string* mGreenPepper;

	mClass02_xy() {
		mGreenPepper = new string("青椒");
		cout << "------ mClass02_xy 的构造函数" << endl;
	}

	virtual void mFun02() = 0;

	// 纯虚析构函数【会让类变成抽象类,类不可实例化】【类外实现】
	virtual ~mClass02_xy() = 0;

};
// 类外实现 mClass02_xy 的析构函数
mClass02_xy::~mClass02_xy() {
	if (mGreenPepper != NULL)
	{
		delete mGreenPepper;
		mGreenPepper = NULL;
	}
	cout << "------ mClass02_xy 的析构函数" << endl;
}

// 小白菜 -- 父类
class mClass03_xy {
public:
	string* mCabbage;

	mClass03_xy() {
		mCabbage = new string("小白菜");
		cout << "------ mClass03_xy 的构造函数" << endl;
	}

	virtual void mFun03() = 0;

	virtual ~mClass03_xy() {
		if (mCabbage != NULL)
		{
			delete mCabbage;
			mCabbage = NULL;
		}
		cout << "------ mClass03_xy 的析构函数" << endl;
	}

};

// 商家的土豆 -- 子类
class mClass001_xy :public mClass01_xy {
public:
	string* mVendor;

	// 实例化的时候就知道是几号商家
	mClass001_xy(string* vendor) {
		mVendor = vendor;
		cout << "------ mClass001_xy 的构造函数" << endl;
	}

	virtual void mFun01() {
		cout << *mVendor << "那里买的" << *mPotato << endl;
	}

	virtual ~mClass001_xy(){
		if (mVendor != NULL)
		{
			delete mVendor;
			mVendor = NULL;
		}
		cout << "------ mClass001_xy 的析构函数" << endl;
	}

};

// 商家的青椒 -- 子类
class mClass002_xy :public mClass02_xy {
public:
	string* mVendor;

	mClass002_xy(string* vendor) {
		mVendor = vendor;
		cout << "------ mClass002_xy 的构造函数" << endl;
	}

	virtual void mFun02() {
		cout << *mVendor << "那里买的" << *mGreenPepper << endl;
	}

	virtual ~mClass002_xy() {
		if (mVendor != NULL)
		{
			delete mVendor;
			mVendor = NULL;
		}
		cout << "------ mClass002_xy 的析构函数" << endl;
	}

};

// 商家的小白菜 -- 子类
class mClass003_xy :public mClass03_xy {
public:
	string* mVendor;

	mClass003_xy(string* vendor) {
		mVendor = vendor;
		cout << "------ mClass003_xy 的构造函数" << endl;
	}

	virtual void mFun03() {
		cout << *mVendor << "那里买的" << *mCabbage << endl;
	}

	virtual ~mClass003_xy() {
		if (mVendor != NULL)
		{
			delete mVendor;
			mVendor = NULL;
		}
		cout << "------ mClass003_xy 的析构函数" << endl;
	}

};

// 青椒土豆丝+清炒小白菜【全在1号商家买的】
void mPurchase01(mClass01_xy* potato, mClass02_xy* greenPepper, mClass03_xy* mCabbage) {
	potato = new mClass001_xy(new string("1号商家"));
	greenPepper = new mClass002_xy(new string("1号商家"));
	mCabbage = new mClass003_xy(new string("1号商家"));
	potato->mFun01();
	greenPepper->mFun02();
	mCabbage->mFun03();
	if (potato != NULL)
	{
		delete potato;
		potato = NULL;
	}
	if (greenPepper != NULL)
	{
		delete greenPepper;
		greenPepper = NULL;
	}
	if (mCabbage != NULL)
	{
		delete mCabbage;
		mCabbage = NULL;
	}
}

// 青椒土豆丝+清炒小白菜【全在2号商家买的】
void mPurchase02(mClass01_xy* potato, mClass02_xy* greenPepper, mClass03_xy* mCabbage) {
	potato = new mClass001_xy(new string("2号商家"));
	greenPepper = new mClass002_xy(new string("2号商家"));
	mCabbage = new mClass003_xy(new string("2号商家"));
	potato->mFun01();
	greenPepper->mFun02();
	mCabbage->mFun03();
	if (potato != NULL)
	{
		delete potato;
		potato = NULL;
	}
	if (greenPepper != NULL)
	{
		delete greenPepper;
		greenPepper = NULL;
	}
	if (mCabbage != NULL)
	{
		delete mCabbage;
		mCabbage = NULL;
	}
}

// 青椒土豆丝+清炒小白菜【土豆和小白菜在1号商家买的,青椒在2号商家买的】
void mPurchase03(mClass01_xy* potato, mClass02_xy* greenPepper, mClass03_xy* mCabbage) {
	potato = new mClass001_xy(new string("1号商家"));
	greenPepper = new mClass002_xy(new string("2号商家"));
	mCabbage = new mClass003_xy(new string("1号商家"));
	potato->mFun01();
	greenPepper->mFun02();
	mCabbage->mFun03();
	if (potato != NULL)
	{
		delete potato;
		potato = NULL;
	}
	if (greenPepper != NULL)
	{
		delete greenPepper;
		greenPepper = NULL;
	}
	if (mCabbage != NULL)
	{
		delete mCabbage;
		mCabbage = NULL;
	}
}

void fun01() {
	mClass01_xy* potato = NULL;
	mClass02_xy* greenPepper = NULL;
	mClass03_xy* mCabbage = NULL;
	mPurchase01(potato, greenPepper, mCabbage);
	cout << endl;
	mPurchase02(potato, greenPepper, mCabbage);
	cout << endl;
	mPurchase03(potato, greenPepper, mCabbage);
}


int main() {

	fun01();
	cout << "------------------分界线------------------" << endl;

	cout << endl;
	system("pause");
	return 0;
}

一点点笔记,以便以后翻阅。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小印丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值