C++多态

目录

多态分为两类:

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

多态满足的条件:

实现的效果:

多态的原理

多态的优点

纯虚函数与抽象类

多态案例--制造饮品


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

最核心的是---父类指针指向子类对象,产生多态

一个接口多个形态

多态分为两类:

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

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

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

1.静态多态的函数地址早绑定,编译阶段确定函数地址;

2.动态多态的函数地址晚绑定,运行阶段确定函数地址;

多态满足的条件:

1.有继承关系

2.子类重写父类的虚函数,子类是否为虚函数都可以

实现的效果:

父类的指针或者引用可以指向子类对象,实现子类对象的函数

class animal
{
public:
	virtual void print()
	{
		cout << "aiaimal-print 调用" << endl;
	}
};
class cat :public animal
{
public:
	void print()
	{
		cout << "cat-print 调用" << endl;
	}
};
void Print(animal& animal1)
{
	animal1.print();
}
void test()
{
	cat cat1;
	Print(cat1);
}

将父类的同名函数设置为虚函数以后,那么全局函数执行的函数地址就由确定变化为了不确定。

多态的原理

当没有使用虚函数技术的时候,父类含有一个成员函数(成员变量与成员函数分开存储,成员函数不属于类上,此时父类是一个空类,大小为1)

当引入虚函数的技术以后,父类的内部结构发生了变化-->父类内部有一个VFPTR(虚函数(表)指针),指向一个VFTABLE(虚函数表),表内存储着虚函数地址入口。

当子类重写同名函数,继承父类数据时,虚函数表内的信息就被子函数的虚函数地址入口信息覆盖

当父类引用或指针指向子类对象时,就会调用子类的函数。

多态的优点

1.代码组织结构清晰

2.可读性强

3.利于前期和后期的扩展和维护

C++开发中提倡利用多态去设计程序架构

感悟:刚开始学习多态时的形式:

父类与子类都有一个同名函数,父类是虚函数

【但是这个与同名函数调用不同,那个是需要作用域区分,这个是传参的问题】

使用方式:设置一个全局函数,传入父类的引用,但是在实际传参中,传的是子类的

函数运行的结果也是子类中的函数

后面学习过程中:

只要父类指针指向子类对象【要调用子类】

后--->该指针直接调用函数即可

//部分代码---
abstract_cacluator* ptr1 = new add;
	abstract_cacluator* ptr2 = new sub;
	ptr1->m_num1 = 100;
	ptr2->m_num1 = 55;
	ptr1->m_num2 = 55;
	ptr2->m_num2 = 30;
	cout << ptr1->m_num1 << " + " << ptr1->m_num2 << " = " << ptr1->get_resualt() << endl;
	cout << ptr2->m_num1 << " - " << ptr2->m_num2 << " = " << ptr2->get_resualt() << endl;

这种情况下,用完记得销毁堆区空间

纯虚函数与抽象类

在多态中,父类中的虚函数的实现毫无意义,可以直接将虚函数设置为纯虚函数

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

当类中存在纯虚函数后,这个类称为抽象类

抽象类的特点:

1.抽象类不允许实例化对象

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

多态案例--制造饮品

#include <iostream>
using namespace std;

class drinking
{
public:
	//煮水
	virtual void boil() = 0;
	//冲泡
	virtual void brew() = 0;
	//倒入
	virtual void pour() = 0;
	//加入
	virtual void putt() = 0;
	//整合到一起
	void makedrink()
	{
		boil();
		brew();
		pour();
		putt();
	}
};

class tea :public drinking
{
public:
	//煮水
	virtual void boil()
	{
		cout << "煮茶水" << endl;
	}
	//冲泡
	virtual void brew()
	{
		cout << "冲泡茶水" << endl;
	}
	//倒入
	virtual void pour()
	{
		cout << "倒入茶叶" << endl;
	}
	//加入
	virtual void putt()
	{
		cout << "放入茶水作料" << endl;
	}
};

class coffee :public drinking
{
public:
	//煮水
	virtual void boil()
	{
		cout << "煮咖啡水" << endl;
	}
	//冲泡
	virtual void brew()
	{
		cout << "冲咖啡水" << endl;
	}
	//倒入
	virtual void pour()
	{
		cout << "倒入咖啡" << endl;
	}
	//加入
	virtual void putt()
	{
		cout << "放入咖啡作料" << endl;
	}
};
void makedrink(drinking* drink)
{
	drink->makedrink();
	delete drink;
	drink = NULL;
}
void test()
{
	makedrink(new tea);
	makedrink(new coffee);
}
int main()
{
	test();
	return 0;
}

父类-制作饮品里面有四个纯虚函数和一个整合函数

子类继承的时候,重写了纯虚函数,子类不是抽象类。同时也继承了整合函数

整合函数会调用自己类的其他函数【找到了正确的函数入口】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hskwcy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值