一个问题

构造函数,静态成员函数,内联函数能不能为virtual函数?

内联函数:编译时展开的,虚函数是为了实现多态,是动态行为,两者是矛盾的。内联函数展开就不存在了,也就不存在函数地址了,无法调用。
但是,由于inline只是向编译器建议,所以编译器不会让inline和virtual同时起作用,所以也不会报错。

构造函数:虚函数使用虚指针调用函数,调用构造函数之前没有构造完成,是没有虚指针的。另外虚函数是在基类指针中调用派生类函数的方式,构造函数不需要也不可能让你这样做。构造时已经知道了这个类的类型,这和虚函数向矛盾

静态成员函数:静态函数没有this指针,无法调用虚函数。另外静态函数属于类,不属于对象,也就不存在对象虚函数为基础的多态。


虚函数表——虚函数的实现方式

想要更加深入理解上面那个问题,需要知道虚函数在C++中的实现方式。

虚函数(Virtual Function)是通过一张虚函数表来实现的。简称为V-Table。在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中分配了指向这个表的指针的内存,所以,当用父类的指针来操作一个子类的时候,这张虚函数表就显得尤为重要了,它就像一个地图一样,指明了实际所应该调用的函数。 —–百度百科

来看一张图片,Class1的实体(对象)中开头是一个指向虚函数表的指针,虚函数表中寸有虚函数的函数指针。Class2类是Class类的子类,对vfunc2()进行了覆写(override),所以vfunc2在Class2中的地址被覆写。

我们可以用visual studio的调试功能做个试验

#include<iostream>using namespace std;class base_1
{
private:
public:virtual void func1A() { cout << "base1 A" << endl; }virtual void func1B() { cout << "base1 B" << endl; }virtual void func1C() { cout << "base1 C" << endl; }
};class base_2
{
private:
public:virtual void func2A() { cout << "base2 A" << endl; }virtual void func2B() { cout << "base2 B" << endl; }virtual void func2C() { cout << "base2 C" << endl; }
};
class childTest:public base_1,public base_2
{
private:
public:virtual void func1A() { cout << "Child A" << endl; }virtual void func1B() { cout << "Child B" << endl; }virtual void func2C() { cout << "chind C" << endl; }
};int main()
{base_1 test;childTest ctest;
}

运行后实体中数据如下

类的实体(对象)的开头有指向虚函数的指针,那么虚函数表究竟在哪里?

类的所有对象共用一张虚函数表。而虚函数表具体位置各个编译器实现不同,有兴趣可以看http://blog.chinaunix.net/uid-26611383-id-3772200.html

关于虚函数机制的更深的内容可以看RednaxelaFX大大在知乎上的这个回答,http://www.zhihu.com/question/27459122

在查询这些资料的时候,很多人都推荐一本书《Inside the C++ objective model 》,看来之后要补一补。

C++ 虚函数实现:虚函数表 虚表指针相关推荐

  1. C++: 虚函数 / 纯虚函数

    虚函数 ● 虚函数是指在基类内部声明的成员函数前添加关键字 virtual 指明的函数 ● 虚函数存在的意义是为了实现多态,让派生类能够重写(override)其基类的成员函数 ● 派生类重写基类的虚 ...

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

    前言 (1)虚基表与虚函数表是两个完全不同的概念 虚基表用来解决继承的二义性(虚基类可以解决). 虚函数用来实现泛型编程,运行时多态. (2)虚函数是在基类普通函数前加virtual关键字,是实现多态 ...

  3. 虚函数、虚函数表、虚继承

    1.虚函数 虚函数的定义: 虚函数必须是类的 非静态成员函数(且非构造函数),其访问权限是public(可以定义为privateor proteceted, 但是对于多态来说,没有意义),在基类的类定 ...

  4. C++虚函数和虚函数表原理

    虚函数的地址存放于虚函数表之中.运行期多态就是通过虚函数和虚函数表实现的. 类的对象内部会有指向类内部的虚表地址的指针.通过这个指针调用虚函数. 虚函数的调用会被编译器转换为对虚函数表的访问: ptr ...

  5. c++ 虚函数及虚函数表

    多态"的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定. #include <iostream> using namesp ...

  6. C++虚函数,虚函数表,虚继承,虚继承表

    一.虚函数 类中用virtual关键字修饰的函数. 作用:主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的 ...

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

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

  8. python虚函数_virtual(虚函数) vtbl(虚函数表)与vptr(虚函数表指针)

    类的虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址 注意的是,编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享.类的每个虚成员占据虚函数表中的一行.如果类 ...

  9. C++虚函数及虚函数表解析

    一.背景知识(一些基本概念) 虚函数(Virtual Function):在基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数. 纯虚函数(Pure Virtual Functi ...

  10. 【C++】虚函数与虚函数表

    1. 虚函数表的结构 #include <iostream> using namespace std;typedef void (*Fun)(void);class Base {publi ...

最新文章

  1. 简易记事本实现与分析(二)辅助类的编写
  2. Python基础第三课
  3. 同一个局域网,不同网段的远程控制
  4. STL——关联式容器
  5. 李婷华 201771010113 《面向对象程序设计(java)》 第二周学习总结
  6. dnf如何快速拾取物品_DNF游戏里的一些便利性功能,每个都非常实用
  7. 开多线程出现importerror_那些年让你迷惑的并行、并发、多线程、多进程、协程...
  8. SendMessage 设置TMemo组件的边界
  9. MegaWizard Plug-in Manager产生的目录结构及关键文件
  10. [Linux] 常用Linux命令
  11. windows和linux通过网线连接,用网线连接Windows和Linux台式机,并实现Linux共享Windows的WiFi网络...
  12. python 第三周测试答案_Python 基础学习 (第三周)
  13. IBM/ORACLE/EMC在银行业的重要性
  14. colspan会影响内部单元格宽度失效_冷轧轧辊失效原因分析及改进措施
  15. 图神经网络初探:build a simple graph nets
  16. IPSAN 配置过程
  17. 如何把Excel两列内容合并成一列内容
  18. Line 10: Char 40: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in ty
  19. Nhibernate+MVC开发小结
  20. 如何写会议 Rebuttal

热门文章

  1. 非科班转码,上岸小公司我也很满意了
  2. 双人版井字棋游戏c语言设计报告,井字棋游戏课程设计总结报告.doc
  3. Excel 宏编程-使用excel宏编写第一个Hello World程序实例演示!
  4. 什么是驻点和拐点_驻点、极值点、拐点、鞍点的区别与联系
  5. C/C++编程学习 - 第20周 ⑩ 量身高
  6. 【数字化】数字档案馆系统测试指标分布总览
  7. ai面试的优缺点_如果你的面试官是机器人?那么你该如何表现?
  8. bzoj1488 图的同构
  9. 用氦气(He)、氖气(Ne)、氩气(Ar)、118号元素(气奥)(Og,放射性,人造元素)组成的激光器
  10. 2018 蓝桥杯 省赛 B组 原题 C语言B组 第二题 第九届蓝桥杯真题+答案+解析