多态一般分为静多态,动多态和宏多态
静多态:在编译时刻确定函数地址(重载,模板)
动多态:在运行时刻确定函数的地址
虚函数:简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。有了虚函数才能实现动多态。
那些能成为虚函数?
1.能取地址
2.依赖对象调用
所以普通的类成员方法、析构(特殊)函数能成为虚函数
普通全局函数、静态的类成员方法、内联函数、构造函数不能成为虚函数
虚函数指针
要在运行时确定,类对象里面就必须有虚函数地址的信息。而在运行的过程中,只会把指令和数据加载到CPU上,所以我们用一个指针,指向一块内存包含虚函数的信息,并且将这个指针存到rodada段,这样我们就能在运行时找到函数的入口地址。
虚函数表:虚函数指针指向的内存,用表来保存虚函数信息
动多态过程
class Base
{
public:
Base(int a) :ma(a)
{
std::cout << "Base::Base(int)" << std::endl;
}
~Base()
{
std::cout << "Base::~Base()" << std::endl;
}
virtual void Show()
{
std::cout << "Base::Show ==> ma:" << ma << std::endl;
}
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int b) :Base(b), mb(b)
{
std::cout << "Derive::Derive(int)" << std::endl;
}
~Derive()
{
std::cout << "Derive::~Derive()" << std::endl;
}
void Show()
{
std::cout << "Derive::Show ==> mb:" << mb << std::endl;
}
private:
int mb;
};
int main()
{
Base* pb = new Derive(10);
pb->show();
return 0;
}
base类的虚函数表
因为一个类一张虚函数表,derive的虚函数表首先继承base的虚函数表,然后将覆盖虚函数的地址,所以pb调用的show方法就是derive的showf方法。