多态
- 介绍
- 虚函数
- 覆盖(重写)
- 多态
- 源码
- 运行结果
- 笔记扩充(函数指针源码)
介绍
本文主要介绍 多态这个概念
(PS:多态只是一种概念形式)
虚函数
1.成员函数前 加上关键词 virtual ,该函数称为虚函数
(PS:static函数除外)
2.虚函数 按照实际 函数类型调用
(PS:如果基类中 有与 子类中有一模一样的函数,则 基类指针 会调用 子类中函数)
覆盖(重写)
1.只要基类中带有 virtual 关键词且 子类中函数 与 基类中函数的类型 函数名 参数一致
(PS:则子类中函数也是 虚函数 并且形成 覆盖)
- 覆盖的条件
1.必须是非静态成员函数
2.基类使用 virtual
3.子类函数 与 基类函数 原型严格相同
多态
1.子类提供了 对 基类虚函数的有效覆盖,通过 指向子类对象的 基类指针,或者 引用子类对象的 基类引用,调用该虚函数,实际调用结果为 子类覆盖版本,而非基类中原始版本
2.一般函数调用是通过 调用对象类型 决定,而多态这是通过调用者指针或引用的 实际目标对象的类型决定。
3.多态 只能通过 引用或指针 表现,且指针更灵活
4.除 构造和析构函数,通过 基类中this指针 可满足多态
- 多态的优点
1.应用程序不必为每一个 子类 编写功能调用,只需要对抽象基类进行处理即可,大大提高程序的可复用性。
2.子类的功能可以被 基类的指针或者引用变量 所调用,这叫向后兼容,可以提供可扩充性和可维护性。
源码
#include<iostream>
#include<string>using namespace std;class Animal
{
public://单参构造Animal(string name):m_name(name){}//说话函数(加上虚继承)virtual void say(){cout << m_name << ":say" << endl;}
protected:string m_name;
};class Dog :public Animal
{
public://单参构造Dog(string name) :Animal(name){}//说话函数void say(){cout << m_name << ":汪汪汪" << endl;}};
void main()
{//Animal 类构造Animal* p = new Animal("动物");//打印说话函数p->say();delete p;//销毁 new空间//Dog 类构造Dog* pd = new Dog("狗");pd->say();//优先调用当前类中的say();(PS:俗称 同名隐藏原则)//基类指针 指向子类对象p = new Dog("狗");//PS:只有以public方式继承才能使用 基类指针p->say();//调用子类中的say();(PS:俗称 覆盖)//基类对象构造Animal a = *p;//此处相当于只重写构造了一个基类,并没有使用到子类对象a.say();//输出为基类对象函数system("pause");
}
运行结果
动物:say
狗:汪汪汪
狗:汪汪汪
狗:say
请按任意键继续. . .
笔记扩充(函数指针源码)
#include<iostream>
#include<string>
using namespace std;
int add(int x, int y){ return x + y; } //加函数int sub(int x, int y){ return x - y; } //减函数int mul(int x, int y){ return x * y; }//乘函数int divi(int x, int y){ return x / y; }//除函数//通过 函数指针(PS:int(*fun)(int, int)) 形式 实现多态效果
int calc(int x, int y, int(*fun)(int, int)){ return fun(x, y); }
//主函数
int main()
{cout << "add结果:" << calc(1, 2, add) << endl;cout << "sub结果:" << calc(5, 2, sub) << endl;cout << "mul结果:" << calc(9, 2, mul) << endl;cout << "divi结果:" << calc(12, 2, divi) << endl;system("pause");return 0;
}