多态用通俗点的话来说就是一种事物有多种形态,在c++中子类通常会在父类的基础上实现一些自己的功能。当我们需要通过调用函数类型的不同来实现不同功能时我们就会使用到多态。
C++的多态必须满足两个条件:
1 必须通过基类的指针或者引用调用虚函数
2 被调用的函数是虚函数,且必须完成对基类虚函数的重写
下面的代码就是多态的一个简单实现,当我们通过A类型的指针或者引用来调用函数时会根据new出来的对象类型产生不同的效果。
#include<iostream>
using namespace std;
class A
{
public:
virtual void get() {
cout << "A" << endl;
}
};
class B :public A
{
public:
virtual void get() {
cout << "B" << endl;
}
};
int main()
{
A* p = new B;
A* q = new A;
p->get();
q->get();
return 0;
}
如果上面的代码去掉virtual关键字输出的就会是两个A,就会形成所谓的静态多态,静态多态在编译期间编译器已经帮我们决定调用哪一个函数,所以相对的上面的代码就叫做动态多态。
在父类中我们最好将析构函数加上virtual关键字,下面的程序没有加vitual
#include<iostream>
using namespace std;
class A
{
public:
~ A() {
cout << "A" << endl;
}
};
class B :public A
{
public:
~ B() {
cout << "B" << endl;
}
};
int main()
{
A* p = new B;
A* q = new A;
delete p;
delete q;
return 0;
}
我们可以看到我们析构一个B对象时并没有调用B的析构函数,这样就会引起内存泄漏。
当我们加上virtual关键字后
成功调用了B的析构函数,同时B再调用父类的析构函数。
多态的原理就是在对象中增加一个虚函数表,同种类型的不同对象都公用一张虚函数表,虚函数表放在代码段,不需要动态开辟和销毁。可以自己在vs下的调试窗口查看虚函数表。
当我们知道多态的原理后就会知道静态成员函数只是属于类的,不与任何对象相关联,所以静态成员函数是无法进行多态的。
内联函数在添加virtual关键字后也会失去它的性质,因为虚函数需要调用时去虚函数表里找,而不是编译时展开。