介绍
本文主要介绍 多态这个概念
(PS:多态只是一种概念形式)
虚函数
1.成员函数前 加上关键词 virtual ,该函数称为虚函数
(PS:static函数除外)
2.虚函数 按照实际 函数类型调用
(PS:如果基类中 有与 子类中有一模一样的函数,则 基类指针 会调用 子类中函数)
覆盖(重写)
1.只要基类中带有 virtual 关键词且 子类中函数 与 基类中函数的类型 函数名 参数一致
(PS:则子类中函数也是 虚函数 并且形成 覆盖)
- 覆盖的条件
1.必须是非静态成员函数
2.基类使用 virtual
3.子类函数 与 基类函数 原型严格相同
多态
1.子类提供了 对 基类虚函数的有效覆盖,通过 指向子类对象的 基类指针,或者 引用子类对象的 基类引用,调用该虚函数,实际调用结果为 子类覆盖版本,而非基类中原始版本
2.一般函数调用是通过 调用对象类型 决定,而多态这是通过调用者指针或引用的 实际目标对象的类型决定。
3.多态 只能通过 引用或指针 表现,且指针更灵活
4.除 构造和析构函数,通过 基类中this指针 可满足多态
- 多态的优点
1.应用程序不必为每一个 子类 编写功能调用,只需要对抽象基类进行处理即可,大大提高程序的可复用性。
2.子类的功能可以被 基类的指针或者引用变量 所调用,这叫向后兼容,可以提供可扩充性和可维护性。
源码
cpp
#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");
}
运行结果
cpp
动物:say
狗:汪汪汪
狗:汪汪汪
狗:say
请按任意键继续. . .
笔记扩充(函数指针源码)
cpp
#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;
}