1. 什么是多态?
“一个接口,多种实现”
多态就是不同对象对同一行为会有不同的状态。(举例 : 学生和成人都去买票时,学生会打折,成人不会)
具体来说:
可以看出来,静态多态是编译器在编译期间完成的,编译器会根据实参类型来选择调用合适的函数,如果有合适的函数可以调用就调,没有的话就会发出警告或者报错。。。比较简单,不做多介绍。
举例:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void x()
{
cout << "Base::x" << endl;
}
void y()
{
x();
cout << "Base::y" << endl;
}
};
class Derive : public Base
{
public:
virtual void x()
{
cout << "Derive::x" << endl;
}
void y()
{
cout << "Derive::y" << endl;
}
};
int main()
{
Base* p = new Derive;
p->y();
return 0;
}
输出结果:
Derive::x
Base::y
注意:x()是虚函数,但y()不是虚函数。所以p->y()
调用的是基类Base的y()
,y()
里面再调用x()
,x()
是虚函数,指向Derive的x()
2. 什么是虚函数
在类的定义中,前面有 virtual 关键字的成员函数就是虚函数。
class base {
virtual int get() ;
};
int base::get()
{
}
注意: 1. virtual 关键字只用在类定义里的函数声明中,写函数体时不用。
2. 派生类中和基类中虚函数同名同参数表的函数,不加virtual也自动成为虚函数
3. 多态的作用
在面向对象的程序设计中使用多态,能够增强程序的可扩充性,即程序需要修改或增加功能的时候,需要改动和增加的代码较少。
多态的作用:
- 不必编写每一子类的功能调用,可以直接把不同子类当父类看,屏蔽子类间的差异,提高代码的通用率/复用率
- 父类引用可以调用不同子类的功能,提高了代码的扩充性和可维护性
举例:交学费
系统要判定是小学生还是中学生还是大学生交学费?
运用多态,在基类Student中添加虚函数 交学费()
,等到执行时再确定到底调用哪个类的处理过程。
4. 多态的实现原理(虚函数表)
多态是用虚函数表实现的。
有虚函数的类都会生成一个虚函数表,这个表在编译时生成。
虚函数表是一个存储虚函数地址的数组,以NULL结尾。
多态如何调用?
满足多态的函数调用,程序运行起来后,根据对象中的虚表指针来找实际应该调用的函数; 而不满足多态的函数在函数编译时就确定函数地址了。
动态绑定与静态绑定?
静态绑定是程序编译时确定程序行为。
动态绑定是程序运行时根据具体的对象确定程序行为。
虚函数和虚表在哪里?
虚函数和普通函数一样在代码段,vs2013测试下,虚表在只读常量区。
基类中这前四个字节的指针叫做虚指针,虚指针指向的虚函数表叫做虚表。
虚表存放的是 虚函数的函数指针