一、虚函数的作用

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

#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. 适合于图像处理方向的SCI期刊杂志列表【转】

    适合于图像处理方向的SCI期刊杂志列表[转]   表1. 适合于图像处理方向的SCI期刊杂志列表 ISSN 期刊名 出版周期 1057-7149 IEEE TRANSACTIONS ON IMAGE ...

  2. yourtour的几种链接

    php,html {:URL('User-Register/index')}    格式:http://www.xxx.com/index.php?g=User&m=User&a=in ...

  3. php json_decode

    php代码 <?php $data='[{"Name":"a1","Number":"123","Con ...

  4. 使用System Sound Services 播放音效(最简单,比较底层),调用AudioServicesPlaySystemSound()

    1.适用范围:一些很小的提示或警告音频. 2.使用限制: 声音长度不能超过30秒 声音文件必须是PCM或IMA4(IMA/ADPCM)格式.(有时候可播放一些特殊的.mp3) 打包成.caf..aif ...

  5. Zabbix 3.0 安装笔记

    Zabbix 3.0 只支持CentOS 7.0以上版本,所以先在虚拟机中安装好CentOS 7.0 x64,并设置好IP,允许虚拟机联网. 1.安装MySQL 从最新版本的linux系统开始,默认的 ...

  6. Lucene.Net+盘古分词->开发自己的搜索引擎

    //封装类 using System;using System.Collections.Generic;using System.Linq;using System.Web;using Lucene. ...

  7. java 获取文件的最后编辑时间

    还是日志的问题,需要把日志文件的一些信息给显示出来,其中就需要显示最后的编辑时间,在网上找的答案... File f = new File(path); SimpleDateFormat sdf = ...

  8. WinSCP 连接 Ubuntu 拒绝的问题

    1.打开配置文件 $ sudo vi /etc/ssh/sshd_config 2.修改操作 PermitRootLogin without-password  修改为 PermitRootLogin ...

  9. 史上最全的maven pom.xml文件教程详解

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  10. Spring 事务传递教程_有实例

    通过这篇文章,你将学习到Spring框架中中事务的传递 简介 在处理Spring管理的事务时,开发人员可以以传播的方式定义事务的行为.换句话说,开发人员能够决定业务方法如何被封装在逻辑和物理事务中.来 ...