一、虚函数的作用

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

#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. SMO推导和代码-记录毕业论文4

    SMO的数学公式通过Platt的论文和看这个博客:http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988419.html,大概弄懂了.推导以后 ...

  2. CentOS7搭建hadoop2.6.4双节点集群

    环境: CentOS7+SunJDK1.8@VMware12. NameNode虚拟机节点主机名:master,IP规划:192.168.23.101,职责:Name node,Secondary n ...

  3. Java数据结构——容器总结

    4大容器——List.Set.Queue.Map List 1.ArrayList 优点:随机访问元素 缺点:插入和移除元素时较慢 2.LinkedList 优点:插入和删除元素 缺点:随机访问方面相 ...

  4. Java抽象类与接口的关系

  5. 天猫装修-全屏代码,和去掉10px

    淘宝装修,不支持float,和position属性 全屏代码 <div style="height:685px;"> <div style="paddi ...

  6. Xcode文档安装

    找到所需文档的下载地址,搜索.dmg 安装位置

  7. (转载)iOS UILabel自定义行间距时获取高度

    本文介绍一下自定义行间距的UILabel的高度如何获取,需要借助一下开源的UILabel控件:TTTAttributedLabel 附下载地址 https://github.com/TTTAttrib ...

  8. Hibernate与Mybatis的概念区别

    首先简单介绍下两者的概念: Hibernate :Hibernate 是当前最流行的ORM框架,对数据库结构提供了较为完整的封装. Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力 ...

  9. nlssort函数的用法以及参数

    NLSSORT,可以用来进行语言排序,且不影响当前会话. 用法示例: 拼音SELECT * FROM TEAM ORDER BY NLSSORT(排序字段,'NLS_SORT = SCHINESE_P ...

  10. 今天讲的是JQ 的动画效果

    老规矩,先贴代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...