返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ 虚函数及虚函数表详解
  • 869
分享到

C++ 虚函数及虚函数表详解

2024-04-02 19:04:59 869人浏览 八月长安
摘要

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

多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定。


#include <iOStream>
using namespace std;
class A
{
public:
    int i;
    virtual void func() {}
    virtual void func2() {}
};
class B : public A
{
    int j;
    void func() {}
};
int main()
{
    cout << sizeof(A) << ", " << sizeof(B);  //输出 8,12
    return 0;
}

 在 32 位编译模式下,程序的运行结果是:

8, 12

如果将程序中的 virtual 关键字去掉,输出结果变为:

4, 8

A * p = new B() 实现多态

对比发现,有了虚函数以后,对象所占用的存储空间比没有虚函数时多了 4 个字节。实际上,任何有虚函数的类及其派生类的对象都包含这多出来的 4 个字节,这 4 个字节就是实现多态的关键——它位于对象存储空间的最前端,其中存放的是虚函数表的地址。

每一个有虚函数的类(或有虚函数的类的派生类)都有一个虚函数表,该类的任何对象中都放着该虚函数表的指针(可以认为这是由编译器自动添加到构造函数中的指令完成的)。 

没有覆盖时的子类,可以看到子类的虚函数表的前面是基类离得虚函数

有覆盖就是

子类对象地址为什么能赋值给父类对象指针?

因为,子类对象地址赋值给父类对象指针,父类对象指针就指向了子类的对象空间,父类操作子类的范围是有限制的,只能操作到子类中父类的范围。

基类和子类各有自己的虚函数表vtbl;不管是基类还是子类实例都会在其内存的开头自动创对象即虚函数表指针vptr, 用来访问所在类的虚函数表

想要实现多态,需要动态绑定,需要父类的指针或父类的引用

父类方法为虚方法,子类覆盖父类的虚方法,才能达到多态

子类中父类没有的方法,父类指针也无法访问到,父类指针只能访问到父类自己有的范围

子类要覆盖父类的方法,就是要函数名参数都必须一样才叫覆盖

再看一个例子


class A {
public:
    virtual void vfunc1();
    virtual void vfunc2();
    void func1();
    void func2();
private:
    int m_data1, m_data2;
};
class B : public A {
public:
    virtual void vfunc1();
    void func1();
private:
    int m_data3;
};
class C: public B {
public:
    virtual void vfunc2();
    void func2();
private:
    int m_data1, m_data4;
};

子类继承父类,子类中有父类的同名方法,访问的是子类的方法,子类会隐藏父类所有的同名方法,即使父类有一个同名的参数不同的方法也是如此。 

多重继承(无虚函数覆盖)

下面,再让我们来看看多重继承中的情况,假设有下面这样一个类的继承关系。注意:子类并没有覆盖父类的函数。 

对于子类实例中的虚函数表,是下面这个样子:

我们可以看到:

1)  每个父类都有自己的虚表。

2)  子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的) 

这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。 

多重继承(有虚函数覆盖) 

下面我们再来看看,如果发生虚函数覆盖的情况。 

下图中,我们在子类中覆盖了父类的f()函数。 

下面是对于子类实例中的虚函数表的图: 

我们可以看见,三个父类虚函数表中的f()的位置被替换成了子类的函数指针。这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了。

任何妄图使用父类指针想调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法,

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C++ 虚函数及虚函数表详解

本文链接: https://lsjlt.com/news/156274.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++ 虚函数及虚函数表详解
    多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定。 #include <iostream> using ...
    99+
    2024-04-02
  • c++虚函数与虚函数表原理
    目录1.什么是虚函数2.虚函数会影响类的内存3.了解虚函数表--->通过虚函数表的指针去访问数据4.虚函数声明1.什么是虚函数 用virtual 修饰的成员函数叫虚函数 小知识...
    99+
    2024-04-02
  • C++ 虚函数与纯虚函数代码详解
    目录什么是虚函数:虚函数的注意事项:存虚函数总结什么是虚函数: 虚函数 是在基类中使用关键字 virtual 声明的函数,在C++ 语言中虚函数可以继承,当一个成员函数被声明为虚函数...
    99+
    2024-04-02
  • C++ 纯虚函数详解
    目录虚函数 纯虚函数总结虚函数  在基类中将一个函数声明为虚函数,使该函数具有虚属性,那么其所有派生函数中该函数的重写都具备了虚属性,也就使得基类指针可以调用派生...
    99+
    2024-04-02
  • 详解C++虚函数表存储位置
    目录前言反汇编相近地址前言 先说结论:虚函数表存储在只读数据段(.rodata)、虚函数存储在代码段(.text)、虚表指针的存储的位置与对象存储的位置相同,可能在栈、也可能在堆或数...
    99+
    2023-05-14
    C++虚函数表存储位置 C++虚函数表存储 C++虚函数表
  • C++ typeid 和虚函数详解
    目录typeid 和虚函数总结typeid 和虚函数 前面咱们讲到 typeid 的操作返回值是 type_info 对象的引用,然后输出返回值的地址是相同的,测试代码如下: #...
    99+
    2024-04-02
  • 怎么实现C++虚函数表中的虚函数
    这篇文章主要介绍“怎么实现C++虚函数表中的虚函数”,在日常操作中,相信很多人在怎么实现C++虚函数表中的虚函数问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么实现C++虚函数表中的虚函数”的疑惑有所帮助!...
    99+
    2023-06-17
  • C++ 虚函数表图文解析
    一、前言 一直以来,对虚函数的理解仅仅是,在父类中定义虚函数,子类中可以重写该虚函数,并且父类指针可以指向子类对象,调用子类的虚函数(多态)。在读研阶段经历的几个项目中,自己所写的类...
    99+
    2024-04-02
  • C/C++中虚函数详解及其作用介绍
    目录概述使用方法关联静态关联动态关联案例1未使用虚函数使用虚拟类案例2总结概述 虚函数 (virtual function) 指可以被子类继承和覆盖的函数. 使用方法 基类声明成员...
    99+
    2024-04-02
  • C++学习之虚函数表与多态详解
    目录概述C++虚函数表指针和虚函数表C++ 虚函数表和多态概述 C++的多态在不同环境下实现方式可能不一样,虚函数表是C++实现多态的一种方式。 问题: 什么情况下C++会使用虚指针...
    99+
    2023-05-14
    C++虚函数表 多态 C++虚函数表 C++ 多态
  • C++虚函数表和虚析构介绍
    目录1、虚函数表2、虚析构1、虚函数表 虚函数表是C++实现多态的基础,多态是面向对象的三大特性之一,多态有利于提高代码的可读性,便于后期代码的扩展和维护。我们都知道多态的实现是基于...
    99+
    2024-04-02
  • C++ 函数重载和函数虚函数
    答案: c++++ 中的函数重载和函数虚函数允许开发者创建具有相同名称但不同参数列表或行为的函数。详细描述:函数重载: 创建具有相同名称但不同参数列表的函数,用于在不同情况下使用具有相似...
    99+
    2024-04-15
    c++ 函数重载 函数虚函数
  • C++虚函数表深入研究
    目录探索虚函数表结构继承基类重写虚函数多基类继承 虚函数表寻找被覆盖的虚函数总结面向对象的编程语言有3大特性:封装、继承和多态。C++是面向对象的语言(与C语言主要区别),所以C++...
    99+
    2024-04-02
  • C++中纯虚函数的实例详解
    目录虚函数和纯虚函数附:纯虚函数的应用总结虚函数和纯虚函数 之前学过虚函数,语法:virtual 返回值类型 函数名(参数列表),然后这个类也就变成的虚基类,然后子类重写父类的虚函数...
    99+
    2024-04-02
  • C++ 虚函数与纯虚函数的使用与区别
    目录什么是虚函数:虚函数的注意事项:纯虚函数纯虚函数的注意事项:虚函数与纯虚函数区别什么是虚函数: 虚函数 是在基类中使用关键字 virtual 声明的函数,在C++ 语言中虚函数...
    99+
    2024-04-02
  • C++虚函数表的原理与使用解析
    目录前言1.虚函数表2.一般继承(无虚函数覆盖)3.一般继承(有虚函数覆盖)4.多重继承(无虚函数覆盖)5.多重继承(有虚函数覆盖)6.安全性6.1 通过父类型的指针访问子类自己的虚...
    99+
    2024-04-02
  • C++中虚函数与纯虚函数的区别有哪些
    小编给大家分享一下C++中虚函数与纯虚函数的区别有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是虚函数:虚函数 是在基类中使用关键字 virtual 声...
    99+
    2023-06-20
  • C++ 函数调试详解:如何调试虚函数中的问题?
    虚函数调试方法:设置断点单步执行;使用 assert() 验证条件;利用调试器工具检查动态类型、函数栈和重新定义虚函数。 C++ 函数调试详解:如何调试虚函数中的问题? 引言 在 C+...
    99+
    2024-05-02
    c++ 虚函数 函数调试
  • C#中的虚函数virtual
    一、简介 虚拟函数从C#的程序编译的角度来看,它和其它一般的函数有什么区别呢?一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,也就是写死了的!而虚...
    99+
    2024-04-02
  • 聊一聊C++虚函数表的问题
    之前只是看过C++虚函数表相关介绍,今天有空就来写代码研究一下。 面向对象的编程语言有3大特性:封装、继承和多态。C++是面向对象的语言(与C语言主要区别),所以C++也拥有多态的特...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作