1.虚函数

虚函数是c++实现多态的有力武器,声明虚函数只需在函数前加上virtual关键字,虚函数的定义不用加virtual关键字。

2.虚函数要点

(1) 静态成员函数不能声明为虚函数

可以这么理解,虚函数是个动态的概念,在运行的时候才决定调用哪个,而静态函数是个静态的概念。更加细化的解释是,静态函数与对象无关,不可以用对象实例调用,显然是与虚函数的概念违背的。

(2)构造函数不能是虚函数

很明显,虚函数表的建立都是在构造函数中进行的,如果构造函数是虚函数的话,就变成了鸡生蛋蛋生鸡的问题了。

(3)析构函数最好是虚函数

析构函数最好是虚函数,除非不想作为基类使用,声明称虚函数是个好习惯,这样delete用父类指针指向的子类对象就可以自动找到子类的析构函数了。

3.虚函数表在内存中的构造(gcc)

虚函数表一般在对象所占内存的最开始的位置。

(1)无继承

无继承的话讨论虚函数无意义,但是需要说明的是此时虚函数按照声明的顺序摆放。

(2)一般继承,无虚函数覆盖

这样的话,虚函数表中先放父类虚函数指针,再按声明顺序摆放自己的虚函数指针

(3)单继承,有虚函数覆盖

子类对象的虚函数表中覆盖父类虚函数的位置放置自己的虚函数指针,其他同(2)

(4)多重继承

多重继承意味着有多个虚函数表,自己独有的虚函数放置在第一个虚函数列表的尾部。


这篇总结实际上是网上的一篇博文总结,该博文总结得非常好,所以我就摘录了过来。

补充:

4.GCC和VC中对虚函数,虚基类内存布局的不同

  要点:在普通继承时没区别,单继承时虚函数表是共享的,但是虚继承时,vc环境下,虚函数指针时不共享的,也就意味着多一个新的虚函数就得额外多一个指针。

5.关于虚函数、多态、内存布局的一个例子

6.多态的相关概念

  比较清楚地描述了重载、隐藏、覆盖的区别

C++ 虚函数表与内存模型的更多相关文章

  1. C++ 虚函数表与多态 —— 虚函数表的内存布局

       C++面试经常会被问的问题就是多态原理.如果对C++面向对象本质理解不是特别好,问到这里就会崩. 下面从基本到原理,详细说说多态的实现:虚函数 & 虚函数表.   1. 多态的本质: 形 ...

  2. C++虚函数和虚函数表

    前导 在上面的博文中描述了基类中存在虚函数时,基类和派生类中虚函数表的结构. 在派生类也定义了虚函数时,函数表又是怎样的结构呢? 先看下面的示例代码: #include <iostream> ...

  3. C++ 关于类与对象在虚函数表上唯一性问题 浅析

    [摘要] 非常多教材上都有介绍到虚指针.虚函数与虚函数表.有的说类对象共享一个虚函数表,有的说,一个类对象拥有一个虚函数表.还有的说,不管用户声明了多少个类对象,可是,这个VTABLE虚函数表仅仅有一 ...

  4. C++对象内存模型2 (虚函数,虚指针,虚函数表)

    从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...

  5. C++对象内存模型2 (虚函数,虚指针,虚函数表)(转)

    class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1(); void func2(); virtual ...

  6. vs查看虚函数表和类内存布局

    虚继承和虚基类 虚继承:在继承定义中包含了virtual关键字的继承关系:     虚基类:在虚继承体系中的通过virtual继承而来的基类,需要注意的是:class CSubClass : publ ...

  7. C++对象的内存分布和虚函数表

    c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数. 1.非静态数据成员被放在每一个对象体内作为对象专有的数据成员.    2.静态数据成员被提取出来放在程序的静态数据 ...

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

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

  9. C++对象的内存布局以及虚函数表和虚基表

    C++对象的内存布局以及虚函数表和虚基表 本文为整理文章, 参考: http://blog.csdn.net/haoel/article/details/3081328 http://blog.csd ...

随机推荐

  1. js的基本概念详解

    来自<javascript高级程序设计 第三版:作者Nicholas C. Zakas>的学习笔记(三) 如果你刚学js,想快速了解到js的基本概念,以下将会是一篇不错的引导文章: 语法 ...

  2. select下拉框选择触发事件

    我一直以来都认为,select 下拉框选择对选项 options 使用 onclick 注册事件即可,如下: <select> <option value="0" ...

  3. spring 异常管理机制

    三.异常处理的几种实现: 3.1.在经典的三层架构模型中,通常都是这样来进行异常处理的: A.持久层一般抛出的是RuntiomeException类型的异常,一般不处理,直接向上抛出. B.业务层一般 ...

  4. mac中用命令行运行mysql

    1,安装mysql 在mysql的官方网站下载 mysql 5.5.23 http://www.mysql.com/downloads/mysql/,根据我的机器的配置情况选择了64bit版本. 2, ...

  5. Qt之界面数据存储与获取(使用setUserData()和userData())

    在GUI开发中,往往需要在界面中存储一些有用的数据,这些数据可以来配置文件.注册表.数据库.或者是server. 无论来自哪里,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例 ...

  6. 安装 ArcGIS Runtime SDK for Android

    ArcGIS for Android 开发:Android 平台搭建 - liyong20080101的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/liyong ...

  7. GCC编译警告和错误

    1 error: expected expression before 'else' else之前无表达式. 2 error: lvalue required as left operand of a ...

  8. CentOS5.5上安装git

    1.尝试用yum安装git失败 [root@localhost usr]# yum install gitLoaded plugins: fastestmirrorLoading mirror spe ...

  9. js createElement

      http://www.w3schools.com/js/js_htmldom_nodes.asp var child = document.getElementById("p1" ...

  10. poj 3087 Shuffle'm Up ( map 模拟 )

    题目:http://poj.org/problem?id=3087 题意:已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块牌归为s ...