本文主要是将零碎的点整理起来方便于复习学习
多态,可分为静态多态和动态多态。静态多态,就是表现在静态联编上,即编译时的多态,如泛型编程,函数重载都属于静态联编。动态多态,就是表现在运行时的多态,在程序运行时,才决定调用什么函数,通过虚函数来实现,换句话说,就是实现“一个接口,多种方法”。本文的多态主要指动态多态。
多态实现条件
实现条件有3个:有继承、有virtual重写、有父类指针指向子类对象。
多态实现原理
当类中声明虚函数时,编译器会在类中生成一个虚函数表,虚函数表是一个存储类成员函数指针的数据结构,虚函数表是由编译器自动生成与维护的。virtual成员函数会被编译器放入虚函数表中当存在虚函数时,每个对象中都有一个指向虚函数表的指针vptr。
Class P
{
public:
virtual void a() //virtual 虚函数 该类P会在编译器中生成一张虚函数表)(vtable)
{
cout << "a" << endl;
}
};
Class C:public P
{
virtual void a()
{
cout << "A" << endl;
}
};``
void f(P *p)
{
//在调用这个函数时,编译器会判断这个函数是否是虚函数
//若不为虚函数则编译器直接调用该成员函数
//若为虚函数,则会根据对象p的vptr指针,从所指虚函数表中查找相应的函数a(),并调用,这个查找和调用的过程是在运行时进行的
p -> a();
}
`
void main()
{
C c;
f(&c);//父类指针指向子类对象,有虚函数重写
}
哪些函数不能定义为虚函数
只有类的成员函数才能定义为虚函数;
内联函数,友元函数,静态成员函数,构造函数皆不能做虚函数。
纯虚函数
纯虚函数是一个在基类中没有定义的虚函数,且要求其派生类都要定义这个虚函数。
形式上为 virtual 函数名(参数) = 0;
如
Class P
{
public:
virtual a() = 0;//纯虚函数
};
具有纯虚函数的类称为抽象类,抽象类不能建立对象,不能作为返回类型和函数参数,但可以声明抽象类的指针,声明抽象类的引用。
多态的目的
便于继承和拓展已存在的代码,达到接口重用。