多态是 C++ 面向对象三大特性之一,思考我们为什么要学习多态?
- 在C++中,多态的实现是通过覆盖(override),而决定是否覆盖函数的关键点在于该基类中的函数是否有关键字 virtual,此函数被称为虚函数。
- 多态的优点
- 代码组织结构清晰
- 可读性强
- 利于前期和后期的扩展以及维护
1. 多态分成两类:
- 静态多态:函数重载和运算符重载属于静态多态,复用函数名
- 动态多态:派生类和虚函数实现运行时多态
2. 静态多态和动态多态的区别:
- 静态多态的函数地址早绑定、编译阶段确定函数地址
- 动态多套的函数地址晚绑定、运行阶段确定函数地址
3. 动态多态满足关系
- 有继承关系
- 子类重写父类中的虚函数(函数返回值类型相同,函数名相同,参数列表相同称为重写)
4. 动态多态的使用
- 父类的指针或引用,执行子类对象
你可以理解为:虚函数最大的用途就是能让父类指向子类
通过案例来了解静态多态和静态多态
#include <iostream>
using namespace std;
//多态
//动物类
class Animal
{
public:
virtual void speak() //虚函数,字节为 4,指针的大小始终为 4
{
cout << "动物在说话" << endl;
}
};
class Cat
{
public:
void speak()
{
cout << "猫在说话" << endl;
}
};
//执行说话的函数
//地址早绑定,在编译的阶段确定了函数地址
//如果执行让猫说话,那么地址不得提前绑定,也就是晚绑定(在Animal前加上关键字 virtual)
void dospeak(Animal &animal) //引用方式; Animal &animal = cat;
{
animal.speak();
}
void test01()
{
Cat cat;
dospeak(cat);
}
int main()
{
test01();
system("pause");
return 0;
}
多态小案例 —— 计算器
案例描述:分别用普通写法和多态技术,设计实现两个操作数进行运算的计算器类
//普通实现
#include <iostream>
using namespace std;
#include <string>
class Calculator
{
public:
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;
}
// 如果要扩展新功能,需要修改源码,在真实开发中题常开闭原则
// 开闭原则:对扩展进行开放,对修改进行关闭
}
int m_num1; //操作数 1
int m_num2; //操作数 2
};
void test01()
{
Calculator c;
c.m_num1 = 10;
c.m_num2 = 5;
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("*") << endl;
}
//利用多态
//实现计算器的抽象类
class abstractcalculator
{
public:
virtual int getresult()
{
return 0;
}
int m_num1;
int m_num2
};
class addcalculator : public abstractcalculator //加法计算器
{
public:
int getresult()
{
return m_num1+m_num2;
}
};
class subcalculator : public abstractcalculator //减法计算器
{
public:
int getresult()
{
return m_num1-m_num2;
}
};
class mulcalculator : public abstractcalculator //加法计算器
{
public:
int getresult()
{
return m_num1*m_num2;
}
};
void test02()
{
// 多态使用条件:父类指针或引用指向子类对象
abstractcalculator *abc=new addcalculator; //开辟在堆区,记得手动释放
abc -> m_num1 = 20;
abc -> m_num2 =40;
cout << abc->m_num1 << "+" << abc -> m_num2 >> "=" >> abc->getresult() << endl;
//用完记得销毁
delete abc;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}