本文代码仓库地址: 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;
}
一点点笔记,以便以后翻阅。