C++ 类和对象 多态 加 案例 ————

1、 多态
·多态时C++面向对象的三大特性之一
类别:
·1)静态多态:函数重载 和 运算符重载属于静态多态,复用函数名
·2)动态多态:派生类和虚函数运行时多态

区别:
·静态多态的函数地址是早已绑定的 - 编译阶段确定函数地址
·动态多态的函数地址晚绑定 - 运行阶段确定函数地址

//动物类
class Animal {
public:
	//Speak函数就是虚函数
	//函数前面加上 virtual 关键字,变成虚函数,那么编译器在编译的时候就不能确定函数的调用了
	virtual void speak(){

		cout << "动物在说话" << endl;
	}


};

//猫类
class Cat :public Animal
{
public:

	void speak()
	{
		cout << "小猫在说话" << endl;
	}
};
class Dog :public Animal {

public:
	void speak()
	{
		cout << "小狗在说话" << endl;
	}
};
//执行说话的函数
//地址早绑定    在编译阶段确定函数地址
//如果执行猫说话 那么这个地址不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
void doSpeak(Animal &animal) //Animal &animal的引用是cat
{
	animal.speak();  //一上来不能确定是谁在说话,传进去的对象不同,才执行确定的函数

}

void test01()
{
	Cat cat;
	doSpeak(cat);

	Dog dog;
	doSpeak(dog);
}

**·**函数参数后面的括号里加上override关键字,来表示这个函数重写了父类函数 void speak() override;
**·**重载函数参数名不同;
**·**重写 函数返回值类型、 函数名相同、 形参列表所有内容完全相同。
**·**动态多态满足条件
1)有继承关系
2)子类要重写父类中的虚函数
**·**动态多态的使用
父类的指针或者引用 指向子类对象

在这里插入图片描述

animal.speak(); 当调用speak函数时,由于指向的是cat的对象,他会从ca的t虚函数表中地址找这个对象;

总结:由于写了一个虚函数,类的内部结构发生了改变,多了一个叫指针(虚函数表指针),指向虚函数表,虚函数表的内部写的是我们虚函数入口的地址,当子类重写了虚函数表,重写了虚函数的时候,他会把自身的虚函数给替换掉,换成子类的函数;但你用弗雷德引用去指向子类的对象的时候,由于本身创建的是子类对象,所以当你调用公共的接口的时候,他会从子类中找确实的入口地址,然后调用

2、多态的案例-计算器类

*案例描述:
分别利用普通写法和多态技术,设计实现两个操作数进行运算的计算器类
多态的优点:
·代码组织结构清晰
·可读性强
·利于前期和后期的扩展和维护

//普通写法
class Calculator {
public:
	int m_Num1;
	int m_Num2;
	int getResult(string oper)
	{
		if (oper == "+")
		{
			return m_Num1 + m_Num2;
		}
		else if (oper == "-")
		{
			return m_Num1 - m_Num2;
		}
		else if (oper == "*")
		{
			return m_Num1 * m_Num2;
		}
	}


};
	void test01()
	{
		Calculator c;
		c.m_Num1 = 10;
		c.m_Num2 = 20;

		cout << c.m_Num1 << "-" << c.m_Num2 << "=" << c.getResult("-")<<endl;
	
		cout << c.m_Num1 << "+" << c.m_Num2 << "=" << c.getResult("+") << endl;

		cout << c.m_Num1 << "*" << c.m_Num2 << "=" << c.getResult("* b ") << endl;
	

		//如果想扩展新的功能,需要修改源码
		//在真实的开发中,提倡  开闭原则
		//开闭原则: 对扩展进行开发,对修改进行关闭
		//普通开发 不利于维护和扩展
	
	}


	//利用多态实现计算器
	//实现计算器抽象类
	class AbstractCalculator
	{
	public:
		virtual int getResult()
		{
			return 0;
		}
		int m_Num1;
		int m_Num2;
	};

	//加法计算器类
	class addCaculator :public AbstractCalculator
	{
	public:
		 int getResult()
		{
			return m_Num1+m_Num2;
		}

	};

	//减法计算器类
	class SubCaculator :public AbstractCalculator
	{
	public:
		int getResult()
		{
			return m_Num1 - m_Num2;
		}

	};

	//乘法计算器类
	class MulCaculator :public AbstractCalculator
	{
	public:
		int getResult()
		{
			return m_Num1 * m_Num2;
		}

	};

	void test02()
	{
		//多态的使用条件
		//父类指针或者引用指向子类对象


		//
		AbstractCalculator * abc = new addCaculator;
		abc->m_Num1 = 10;
		abc->m_Num2 = 20;

		cout << abc->m_Num1 << "+" << abc->m_Num2 << " = " << abc->getResult() << endl;
		//指针 计算器是 new出来的 创建的一个堆区  对取数据可以手动释放
		//用完后记得手动销毁
		delete abc;
	
		//指针是一个父类的指针 销毁掉了是指的是堆区的数据给释放了,但是指针的类型没有变 还是父类的指针
		abc = new SubCaculator;
		abc->m_Num1 = 10;
		abc->m_Num2 = 20;
		cout << abc->m_Num1 << "-" << abc->m_Num2 << " = " << abc->getResult() << endl;
		delete abc;
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值