一、虚函数的作用

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

#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=&triangle;
graph->showArea(); Circle circle(2);
graph=&circle;
graph->showArea();
return 0;
}

输出如下,

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

示例代码:

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

输出结果:

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

二、虚函数表

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

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

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

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

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

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

对C++虚函数、虚函数表的简单理解的更多相关文章

  1. C++学习 - 虚表,虚函数,虚函数表指针学习笔记

    http://blog.csdn.net/alps1992/article/details/45052403 虚函数 虚函数就是用virtual来修饰的函数.虚函数是实现C++多态的基础. 虚表 每个 ...

  2. C++ - 类的虚函数\虚继承所占的空间

    类的虚函数\虚继承所占的空间 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24236469 char占用一个字节, 但不满足4的 ...

  3. 虚函数&&虚继承

    如果说没有虚函数的虚继承只是一个噩梦的话,那么这里就是真正的炼狱.这个C++中最复杂的继承层次在VS上的实现其实我没有完全理解,摸爬滚打了一番也算得出了微软的实现方法吧,至于一些刁钻的实现方式我也想不 ...

  4. C++基础 (6) 第六天 继承 虚函数 虚继承 多态 虚函数

    继承是一种耦合度很强的关系 和父类代码很多都重复的 2 继承的概念 3 继承的概念和推演 语法: class 派生类:访问修饰符 基类 代码: … … 4 继承方式与访问控制权限 相对的说法: 爹派生 ...

  5. python 基础内置函数表及简单介绍

    内建函数名 (表达形式) 主要作用 备注 abs(x) 返回一个X值得绝对值(x=int/float/复数) all(iterable) 如果 iterable 的所有元素均为 True(或 iter ...

  6. 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数

    一.多态 多态性是面向对象程序设计的重要特征之一. 多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同的行为. 多态的实现: 函数重载 运算符重载 模板 虚函数 (1).静态绑定与动态绑 ...

  7. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

  8. C++ 由虚基类 虚继承 虚函数 到 虚函数表

    //虚基类:一个类可以在一个类族中既被用作虚基类,也被用作非虚基类. class Base1{ public: Base1(){cout<<"Construct Base1!&q ...

  9. C++ 中的虚函数表及虚函数执行原理

    为了实现虚函数,C++ 使用了虚函数表来达到延迟绑定的目的.虚函数表在动态/延迟绑定行为中用于查询调用的函数. 尽管要描述清楚虚函数表的机制会多费点口舌,但其实其本身还是比较简单的. 首先,每个包含虚 ...

随机推荐

  1. eshop截取字符串长度 和去掉省略号

    <!-- {if $goods.goods_brief} --> {$goods.goods_brief|truncate:17}<!-- {/if} --> 去掉省略号: 找 ...

  2. AppDelegate方法中文记录

    /// 在程序启动之后,重写自定义设置的位置 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOption ...

  3. python 多线程学习

    多线程(multithreaded,MT),是指从软件或者硬件上实现多个线程并发执行的技术 什么是进程? 计算机程序只不过是磁盘中可执行的二进制(或其他类型)的数据.它们只有在被读取到内存中,被操作系 ...

  4. YII2 Model 类切换数据库连接

    配置多数据库: return [ // ... 'components' => [ // ... 'db' => [ 'class' => 'yii\db\Connection', ...

  5. 跨区域的application共享问题。

    @1 new Thread(){ @Override public void run() { getConnect(); } }.start(); 如果我们的一个的应用程序有俩个入口.那么如果我们在这 ...

  6. oarcle数据库导入导出,创建表空间

    oracle导入导出(前提,本机已经安装oracle和oracle客户端)导出命令: exp username/password@192.168.1.138/ORCL file=c:\test.dmp ...

  7. JS中document对象和window对象有什么区别

    简单来说,document是window的一个对象属性.Window 对象表示浏览器中打开的窗口.如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 windo ...

  8. 如何使用jquery - ui 的图标icons 及图标的相对位置 +jquerui是如何来显示图标的?

    1. 只需要引入 jquery-ui 的主css文件: jquery-ui.css 文件?? 不需要 引入 jquery-ui-structure/theme.css文件??? ,,,,, 2. 一定 ...

  9. php中的正则函数主要有三个-正则匹配,正则替换

    php中变量的声明? 由于php声明变量的时候, 不支持使用 var关键字, 又不能直接写一个变量名字, 孤零零的放在那里, 所以, 在php中声明变量的方式, 同时也是给变量初始化的形式, 即: & ...

  10. HTTP状态301、404、200、304分别表示什么意思

    301 (永久移动)请求的网页已永久移动到新位置.服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置.您应使用此代码告诉 Googlebot 某个网页或网站已永久移动 ...