一、虚函数的作用
以一个通用的图形类来了解虚函数的定义,代码如下:
#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]()。
这样就保证每个子类都调用的都是自己对应的虚函数了。
时间: 2024-10-01 04:59:53