菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
376
0

C++中多态(阉割版)

原创
05/13 14:22
阅读数 57477

多态的基本概念

多态是C++面向对象的三大特性之一

多态分为两类

静态多态:函数重载和运算符重载属于静态多态,复用函数名

动态多态:派生类和虚函数实现运行时多态

静态多态和动态多态的区别:

静态多态的函数地址早绑定-编译阶段确定函数地址

动态多态的函数地址晚绑定-运行阶段确定函数地址

动态多态满足条件

1、有继承关系

2、子类重写父类的虚函数

动态多态使用

父类的指针或引用 执行子类对象

多态好处

1、组织结构性强

2、可读性强

3、对于前期和后期拓展以及维护性高

纯虚函数和抽象类

在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容

因此可以将虚函数改为纯虚函数

语法

virtual 返回值类型 函数名 (参数列表)=0;

当类中有纯虚函数,这个类也称为抽象类

抽象类特点:

无法实例化对象

子类必须重写抽象类中的纯虚函数,否则也属于抽象类

#include<iostream>
using namespace std;
#include<string>
class animal
{
public:
	virtual void speak() = 0;
    //只要有一个纯虚函数,这个类称为抽象类
    //抽象类特点:
    //1、无法实例化对象
    //2、抽象类的子类 必须要重写父类中的纯虚函数,否则也属于抽象类,且无法实例化对象
};
class lion: public animal
{
public:	
	void speak()
	{
		cout << "狮子吼叫" << endl;
	}
};
void test01()
{
	lion L;
	L.speak();
	animal* an = new lion;
	an->speak();	
	delete an;
}
int main()
{
	test01();
	system("pause");
	return 0;
}
 

做菜案例:

#include<iostream>
using namespace std;
#include<string>
class abstructCooking
{
public:
	//买菜
	virtual void Buy() = 0;
	//洗菜
	virtual void Wash() = 0;
	//切菜
	virtual void Cut() = 0;
	//起锅烧油
	virtual void Hotpot() = 0;
	//炒菜
	virtual void Make() = 0;
	//出锅
	virtual void Puttable() = 0;
};
class Fish: public abstructCooking
{
public:	
	//买菜
	virtual void Buy()
	{
		cout << "在菜市场买一条大花鲢鱼" << endl;
	}
	//洗菜
	virtual void Wash()
	{
		cout << "买来的花鲢咱们给它清洗干净" << endl;
	}
	//切菜
	virtual void Cut()
	{
		cout << "咱们给它改一下刀" << endl;
	}
	//起锅烧油
	virtual void Hotpot()
	{
		cout << "起锅烧油,放入葱姜蒜花椒八角桂皮香叶小茴香干辣椒" << endl;
	}
	//炒菜
	virtual void Make()
	{
		cout << "加入郫县豆瓣酱,炒出红油,下入花鲢,一罐啤酒开大火炖" << endl;
	}
	//出锅
	virtual void Puttable()
	{
		cout << "摆盘出锅" << endl;
	}
	
};
class Meat : public abstructCooking
{
public:
	//买菜
	virtual void Buy()
	{
		cout << "在菜市场买一条新鲜猪五花" << endl;
	}
	//洗菜
	virtual void Wash()
	{
		cout << "买来的五花肉咱们给它清洗干净" << endl;
	}
	//切菜
	virtual void Cut()
	{
		cout << "咱们给它改一下刀" << endl;
	}
	//起锅烧油
	virtual void Hotpot()
	{
		cout << "起锅烧油,放入葱姜蒜花椒八角桂皮香叶小茴香干辣椒" << endl;
	}
	//炒菜
	virtual void Make()
	{
		cout << "加入郫县豆瓣酱,炒出红油,下入猪肉,一罐啤酒开大火炖" << endl;
	}
	//出锅
	virtual void Puttable()
	{
		cout << "摆盘出锅" << endl;
	}

};

void dowork(abstructCooking* cook)
{
	cook->Buy();
	cook->Wash();
	cook->Cut();
	cook->Hotpot();
	cook->Make();
	cook->Puttable();
	
	delete cook;
}
void test01()//调用做菜函数
{
	dowork(new Fish);
	cout << "-------------------------------------" << endl;
	dowork(new Meat);
}
int main()
{
	test01();
	system("pause");
	return 0;
}
 

虚析构和纯虚析构

多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放是无法调用到子类的析构代码

解决方式:将父类中的析构函数改为虚析构或者纯虚析构

虚析构和纯虚析构共性:

可以解决父类指针释放子类对象

都需要有具体的函数实现

虚析构和纯虚析构区别:
如果是纯虚析构,该类属于抽象类,无法实例化对象

通过虚析构实现

#include<iostream>
using namespace std;
#include<string>

class Animal
{
public:
	Animal()										
	{
		cout << "Animal的构造函数" << endl;
	}
	virtual ~Animal()
	{
		cout << "Animal的析构函数" << endl;
	}
	//动物叫
	virtual void speak() = 0;
	
};
class Lion: public Animal
{
public:	
	Lion(string name)
	{
		cout << "Lion的构造函数" << endl;
		this->name = name;
	}
	 ~Lion()
	{
		cout << "Lion的析构函数" << endl;
	}
	virtual void speak()
	{
		cout <<name<< "狮子咆哮" << endl;
	}
	string name;
};

void test01()
{
	Animal* an = new Lion("辛巴");
	an->speak();
	delete an;
	
}
int main()
{
	system("color B1");
	test01();
	system("pause");
	
	return 0;
}
 

通过纯虚析构实现

#include<iostream>
using namespace std;
#include<string>
#include<windows.h>
class Animal
{
public:
	Animal()										
	{
		cout << "Animal的构造函数" << endl;
	}
	virtual ~Animal() = 0;
	
	//动物叫
	virtual void speak() = 0;
	
};
Animal::~Animal()
{
	cout << "Animal的析构函数" << endl;
}
//和包含普通纯虚函数的类一样,包含了纯虚析构函数的类也是一个抽象类。不能够被实例化。
class Lion: public Animal
{
public:	
	Lion(string name)
	{
		cout << "Lion的构造函数" << endl;
		this->name = name;
	}
	 ~Lion()
	{
		cout << "Lion的析构函数" << endl;
	}
	virtual void speak()
	{
		cout <<name<< "狮子咆哮" << endl;
	}
	string name;
};

void test01()
{
	Animal* an = new Lion("辛巴");
	an->speak();
	delete an;
	
}
int main()
{
	system("color B1");
	test01();
	/*SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
	printf("Hello");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
	printf(" World!");*/
	system("pause");
	
	return 0;
}
 

发表评论

0/200
376 点赞
0 评论
收藏
为你推荐 换一批