【摘要】

非常多教材上都有介绍到虚指针、虚函数与虚函数表。有的说类对象共享一个虚函数表,有的说,一个类对象拥有一个虚函数表。还有的说,不管用户声明了多少个类对象,可是,这个VTABLE虚函数表仅仅有一个。也有的在说,每一个具有虚函数的类的对象里面都有一个VPTR虚函数指针,这个指针指向VTABLE的首地址,每一个类的对象都有这么一种指针。今天。我们就来解决问题,同一个类的不同对象,是不是拥有“同样”的虚函数表,这个同样是物理上的同样(内存地址)还是逻辑上的同样(数据结构)。本文现详述例如以下。

【正文】

虚指针:每一个含有虚方法(虚函数)对象里有虚表指针。指向虚表。

虚函数表:虚函数表是顺序存放虚函数地址的,虚表是顺序表,表里存放了虚函数的地址。

C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——假设有多层继承或是多重继承的情况下)。

这意味着我们通过对象实例的地址得到这张虚函数表。然后就能够遍历当中函数指针,并调用对应的函数。

【代码演示样例】

#include <iostream>
using namespace std; class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; } };
typedef void(*Fun)(void); int main()
{
Fun pFun = NULL;
Base obj_1,obj_2;
// obj_1 虚函数表 — 第一个函数
pFun = (Fun)*((int*)*(int*)(&obj_1));
pFun();
pFun = (Fun)*(((int*)*(int*)(&obj_1))+1);
pFun();
// 输出 虚函数表地址 与 虚函数表元素 的值
cout << "obj_1 虚函数表地址:" << (int*)(&obj_1) << endl;
cout << "obj_2 虚函数表地址:" << (int*)(&obj_2) << endl;
cout << "obj_1 虚函数表 — 第一个函数地址:" << (int*)*(int*)(&obj_1) << endl;
cout << "obj_2 虚函数表 — 第一个函数地址:" << (int*)*(int*)(&obj_2) << endl;
return 0;
}
/*
输出 :
Base::f
Base::g
obj_1 虚函数表地址:0018FF40
obj_2 虚函数表地址:0018FF3C
obj_1 虚函数表 — 第一个函数地址:0046F0AC
obj_2 虚函数表 — 第一个函数地址:0046F0AC
Press any key to continue
*/

【结论】

不同对象虚函数表表中元素是相等的。逻辑上是一样的,存放的都是类中虚函数的地址;

不同对象虚函数表的内存地址是不一样,物理上是不一样的,一个对象是一个新的表。

【相关推荐】

详见:C++ 虚函数表解析

详址:http://blog.csdn.net/haoel/article/details/1948051#comments

C++ 关于类与对象在虚函数表上唯一性问题 浅析的更多相关文章

  1. C++类成员空间分配和虚函数表

    最近在自学python,看到继承和类,就顺便复习了C++的类和继承等方面的知识. 先看Base基类 class Base { private: virtual void display() { cou ...

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

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

  3. C++ 类的存储方式以及虚函数表

    一.C++成员函数在内存中的存储方式 用类去定义对象时,系统会为每一个对象分配存储空间.如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间.按理说,如果用同一个类定义了10个对象,那么就 ...

  4. C++ Daily 《5》----虚函数表的共享问题

    问题: 包含一个以上虚函数的 class B, 它所定义的 对象是否共用一个虚函数表? 分析: 由于含有虚函数,因此对象内存包含了一个指向虚函数表的指针,但是这个指针指向的是同一个虚函数表吗? 实验如 ...

  5. C++虚函数表

    大家知道虚函数是通过一张虚函数表来实现的.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆盖的问题,其内容真是反应实际的函数.这样,在有虚函数的类的实例中,这个表分配在了这个实例的内存中 ...

  6. 对C++虚函数、虚函数表的简单理解

    一.虚函数的作用 以一个通用的图形类来了解虚函数的定义,代码如下: #include "stdafx.h" #include <iostream> using name ...

  7. C++虚函数与虚函数表

    多态性可分为两类:静态多态和动态多态.函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的. 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说 ...

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

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

  9. C++ 虚函数表与内存模型

    1.虚函数 虚函数是c++实现多态的有力武器,声明虚函数只需在函数前加上virtual关键字,虚函数的定义不用加virtual关键字. 2.虚函数要点 (1) 静态成员函数不能声明为虚函数 可以这么理 ...

随机推荐

  1. Android view相关与自定义View

    一.关于view的机制的问答 1.gesturedetector和ontouchevent的区别 gesturedetector指的是手势检测器,根据动态手势的运动特性,提出了速率边沿检测算法来分割手 ...

  2. A.Equals(B)和A==B的区别

    Equals 和 == 都是用于比较. 如果a和b都是值类型,则a.Equals(b) 和 a == b 结果相同,但是在引用类型是它们的行为是不同的: string a = new string(n ...

  3. xml读取 避开并发(xml的一些操作)

    很多地方读取文件可能会出现并发现象 处理: 使用FileMode.Open, FileAccess.Read, FileShare.ReadWrite 避开并发 public static List& ...

  4. git 使用报错记录

    错误一:git fatal: unable to write new index file主要原因就是服务器磁盘空间不够导致的,增加服务器空间就OK了在百度上面搜索没得到什么有效信息,在gooogle ...

  5. 利用Docker搭建本地https环境的完整步骤

    利用Docker搭建本地https环境的完整步骤 这篇文章主要给大家介绍了关于如何利用Docker搭建本地https环境的完整步骤,文中通过示例代码将实现的步骤介绍的非常详细,对大家的学习或者工作具有 ...

  6. ThreadPool基础之RegisterWaitForSingleObject

    原文发布时间为:2010-10-27 -- 来源于本人的百度文章 [由搬家工具导入] 首先我们看一下它的原型: Codepublic static RegisteredWaitHandle Regis ...

  7. 给页面上所有的a标签增加随机数每次点击保证最新

    $(document).click(function(){ $("a").each(function(){ if($(this).parent().parent().hasClas ...

  8. k-mean聚类学习笔记

    才发现k-means 聚类这么简单,-_-|| 首先讲一下最朴素的k-means, 首先k-means 是一个迭代过程. 所以我们需要先确定初始,最简单的一个办法就是随机从样本中抽取k个出来,作为初始 ...

  9. Codeforces Round #442 Div.2 A B C D E

    A. Alex and broken contest 题意 判断一个字符串内出现五个给定的子串多少次. Code #include <bits/stdc++.h> char s[110]; ...

  10. 八、 Java程序初始化的顺序(一)

    今天在写构造器方法的时候,遇到了一个小问题,由这个问题引发了一连串的思考,在一个Java类中变量与类的初始化执行顺序是什么样的呢?## 发现问题 class Student{ private Stri ...