C++中多态原理:VPTR虚函数表

一多态产生的条件:

  1有子类继承父类

  2存在虚函数重写

  3父类指针指向子类对象,或是父类引用子类对象

 

二虚函数表和vptr指针

  1当类中声明虚函数时,编译器会在类中生成一个虚函数表

  2虚函数表示一个存储类成员函数指针的数据结构

  3虚函数表是由编译器自动生成与维护的

  4virtual成员函数会被编译器放入虚函数表中

  5存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)

 

三多态中的动态联编:

  在符合多态条件下, 当调用类的成员函数时,vptr指针会先在虚函数表中依次查找,直到找到符合的函数。

 

  说明:1通过虚函数表指针vptr调用重写函数是在程进行的序运行时,因此需要寻址操作才能确定真正应该调用的函数。而普通成员函数时在编译时就确定了调用的函数。所以在效率上,虚函数的效率要低得多。

  2处于效率考虑,没必要将所有成员函数 都声明为虚函数

  3C++编译器,执行虚函数,不需要区分是子类对象还是父类对象,而是直接通过p的vptr指针指向的对象函数执行即可。

 

四构造函数中能否调用虚函数实现多态的问题:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Parent
{
public:
Parent(int a = 0)
{
this->a = a;
print();
}
virtual void print()
{
cout << "I'm Parent" << endl;
}
private:
int a;
};

class Child :public Parent
{
public:
Child(int a = 0, int b = 0) :Parent(a)
{
this->b = b;
print();
}
virtual void print()
{
cout << "I'm Son" << endl;
}
private:
int b;
};

void HowToPlay(Parent* base)
{
base->print();
}

int main(void)
{
Child c1;
HowToPlay(&c1);

system("pause");
return 0;
}

打印结果:

    父类对象指向子类,父类构造函数中的虚函数print答应的依然是父类的成员函数,这个过程没有发生多态。调用HowToPlay时,发生多态。所以这种情况下,构造函数中调用虚函数是不能发生多态的。

   关于vptr指针的初始化,是分部进行的,先指向并初始化父类VPTR表,再指向并初始化子类VPTR表。

posted on 2016-08-11 09:40  A-祥子  阅读(1435)  评论(0)    收藏  举报

导航