一.多态的初识
静态函数 函数重载
动态函数 继承和虚函数
1.什么是多态
通过父类的指针调用实际的子类成员函数,使父类指针有多种形态
2.多态基于什么实现
基于虚函数实现,虚函数要在子类中重写
注意:构造函数不能为虚函数(执行构造函数前对象尚未完成创建,虚函数表还不存在)
3构成多态的条件
->>>>必须有继承
->>>>必须有同名虚函数
->>>>父类指向子类(引用或指针) 并通过父类调用虚函数
4.虚函数的实现原理
重写:父类虚函数在子类中重新实现
覆盖:如果子类中有父类虚函数的重写 就会覆盖子类的虚函数列表
通过函数指针,所有的虚函数的指针组成了一个虚函数列表(vTable)
需要一个记录当前对象使用的是哪个虚函数列表的虚指针(vfptr),虚指针包含着当前对象的前四个字节中
当通过父类指针调用子类函数时,就会通过vfptr找到当前的虚函数列表,通过虚函数列表中的函数指针调用
在子类中重写虚函数就会覆盖虚函数列表中的内容(虚函数列表中的函数指针由父类变成子类)
vTable:虚函数列表(函数指针数组),在编译期存在,所有的这个类共享一个虚函数列表
vfptr: 虚指针(二级函数指针),用来指向当前对象所使用的虚函数列表
5.优缺点:
优点:提高复用性和拓展性
缺点:安全性、空间、效率
下面请看实例
//#include <iostream>
//using namespace std;
//class Drink
//{
//public:
// virtual void Show()
// {
// cout << "Drink" << endl;
// }
//};
//class Milk:public Drink
//{
//public:
// void Show()
// {
// cout << "Milk" << endl;
// }
//};
//class Coffee :public Drink
//{
//public:
// void Show()
// {
// cout << "Coffee" << endl;
// }
//};
//class Water :public Drink
//{
//public:
// void Show()
// {
// cout << "Water" << endl;
// }
//};
void Glass(Milk& rm)
{
rm.Show();
}
void Glass(Coffee& rc)
{
rc.Show();
}
void Glass(Water& rw)
{
rw.Show();
}
//void Glass(Drink &rd)
//{
// rd.Show();
//}
//void Glass(Drink* pd)
//{
// pd->Show();
//}
//int main()
//{
// Milk m;
// Coffee c;
// Water w;
//
// Glass(c);
// Glass(w);
// Glass(m);
// cout << "--------------------" << endl;
// Glass(&c);
// Glass(&w);
// Glass(&m);
// system("pause");
// return 0;
//}