您的位置:首页 > 编程语言 > C语言/C++

对C++虚函数、虚函数表的简单理解

2016-06-18 17:30 399 查看

一、虚函数的作用

以一个通用的图形类来了解虚函数的定义,代码如下:

#include "stdafx.h"
#include <iostream>
using namespace  std;

class Graph
{
protected:
double x;
double y;
public:
Graph(double x,double y)
{
this->x=x;
this->y=y;
}
virtual void showArea()
{
cout<<"计算图形面积"<<endl;
}
};

class Rectangle:public Graph
{
public:
Rectangle(double x,double y):Graph(x,y){};
virtual void showArea()
{
cout<<"矩形面积为:"<<x*y<<endl;
}
};

class Triangle:public Graph
{
public:
Triangle(double d,double h):Graph(d,h){};
virtual void showArea()
{
cout<<"三角形面积为:"<<x*y*0.5<<endl;
}
};

class Circle:public Graph
{
public:
Circle(double r):Graph(r,r){};
virtual void showArea()
{
cout<<"圆形面积为:"<<3.14*x*y<<endl;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
Graph *graph;

Rectangle rectangle(10,5);
graph=&rectangle;
graph->showArea();

Triangle triangle(5,2.4);
graph=▵
graph->showArea();

Circle circle(2);
graph=&circle;
graph->showArea();
return 0;
}

输出如下,





该代码的作用是,设计不同的类去处理不同的图形,所有类继承于同一个Graph类。但是每个图形类都有一个相同的函数showArea。如果有需求是输出多个图形的面积,如果没有虚函数,就需要给每一种图形设计一个数组,然后每种图形分别处理。但是有了虚函数后,不管是什么图形,都只要设计一个Graph数组,然后调用每个成员的showArea函数即可。

示例代码:

Graph* gArray[3];
gArray[0] = &rectangle;
gArray[1] = ▵
gArray[2] = &circle;
for (int i = 0;i < 3;i++)
{
gArray[i]->showArea();
}

输出结果:





为什么会有这样的效果呢?原因就是有虚函数表。


二、虚函数表


调试上面的图形类代码,用IDE里的调试工具查看每个类对象;





每个对象(事实上,所有相同的类对象,都共用一个虚函数表)都有一个__vfptr成员数组,这个__vfptr就是虚函数表,偏移在基类和继承类中都是一样的,所以虚函数表可以在基类中访问到。

但是仔细查看上面的图,可以看到,每个对象的虚函数表数组都是指向的不同的地址,分别指向自己类中的虚函数。

所以如果指定graph->showArea()

调用的函数是graph->__vfptr[0]()。

这样就保证每个子类都调用的都是自己对应的虚函数了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: