对C++虚函数、虚函数表的简单理解
一、虚函数的作用
以一个通用的图形类来了解虚函数的定义,代码如下:
#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]()。
这样就保证每个子类都调用的都是自己对应的虚函数了。
对C++虚函数、虚函数表的简单理解的更多相关文章
- C++学习 - 虚表,虚函数,虚函数表指针学习笔记
http://blog.csdn.net/alps1992/article/details/45052403 虚函数 虚函数就是用virtual来修饰的函数.虚函数是实现C++多态的基础. 虚表 每个 ...
- C++ - 类的虚函数\虚继承所占的空间
类的虚函数\虚继承所占的空间 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24236469 char占用一个字节, 但不满足4的 ...
- 虚函数&&虚继承
如果说没有虚函数的虚继承只是一个噩梦的话,那么这里就是真正的炼狱.这个C++中最复杂的继承层次在VS上的实现其实我没有完全理解,摸爬滚打了一番也算得出了微软的实现方法吧,至于一些刁钻的实现方式我也想不 ...
- C++基础 (6) 第六天 继承 虚函数 虚继承 多态 虚函数
继承是一种耦合度很强的关系 和父类代码很多都重复的 2 继承的概念 3 继承的概念和推演 语法: class 派生类:访问修饰符 基类 代码: … … 4 继承方式与访问控制权限 相对的说法: 爹派生 ...
- python 基础内置函数表及简单介绍
内建函数名 (表达形式) 主要作用 备注 abs(x) 返回一个X值得绝对值(x=int/float/复数) all(iterable) 如果 iterable 的所有元素均为 True(或 iter ...
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数
一.多态 多态性是面向对象程序设计的重要特征之一. 多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同的行为. 多态的实现: 函数重载 运算符重载 模板 虚函数 (1).静态绑定与动态绑 ...
- 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)
本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上? 成员函数可以被看作是类 ...
- C++ 由虚基类 虚继承 虚函数 到 虚函数表
//虚基类:一个类可以在一个类族中既被用作虚基类,也被用作非虚基类. class Base1{ public: Base1(){cout<<"Construct Base1!&q ...
- C++ 中的虚函数表及虚函数执行原理
为了实现虚函数,C++ 使用了虚函数表来达到延迟绑定的目的.虚函数表在动态/延迟绑定行为中用于查询调用的函数. 尽管要描述清楚虚函数表的机制会多费点口舌,但其实其本身还是比较简单的. 首先,每个包含虚 ...
随机推荐
- C#读写文本文件
static public string Read(string path) { StreamReader sr = new StreamReader(path,Encoding.Default); ...
- Servlet之Filter详解
参考文献:http://www.cnblogs.com/zlbx/p/4888312.html Filter,过滤器,顾名思义,即是对数据等的过滤,预处理过程.为什么要引入过滤器呢?在平常访问网站的时 ...
- Codeforces 719B Anatoly and Cockroaches(元素的交叉排列问题)
题目链接:http://codeforces.com/problemset/problem/719/B 题目大意: 有一队蟑螂用字符串表示,有黑色 ‘b’ 和红色 'r' 两种颜色,你想使这队蟑螂颜色 ...
- ecshop程序结构说明
文件夹说明 名称 备注(作用或意义) 根目录 前台程序文件 admin 后台程序文件 admin/help 功能的帮助文件 admin/images 后台页面用图片 admin/includes 后台 ...
- Ubuntu terminal 不见了
Python出问题了,卸载Python后,terminal竟然消失了.. Ctrl + Alt + T出现的是XTerm 解决办法: 在XTerm中输入命令: # sudo apt-get insta ...
- 正则表达式分组()、不捕获(?:)和断言(?<=)详解
分组 分组在正则中用()表示,根据小菜理解,分组的作用有两个: 1.将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果. 2.分组之后,可以通过后向引用简化表达式(\1 或者$1). ...
- Java并发编程核心方法与框架-CyclicBarrier的使用
CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了Cyc ...
- CSS3导航效果
来自codepen http://codepen.io/mouradhamoud/pen/RRvVZp <!DOCTYPE html> <html> <head> ...
- C# MVC EF中匿名类使用
控制器中代码: var list = context.Says.Join( context.Users, a => a.UserId, b => b.Id, (a, b) => ne ...
- org.hibernate.QueryException: could not resolve property
org.hibernate.QueryException: could not resolve property HibernateSQLXML org.hibernate.QueryExcepti ...


