iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >深入解析C++中的虚函数与多态
  • 130
分享到

深入解析C++中的虚函数与多态

虚函数多态 2022-11-15 23:11:48 130人浏览 安东尼
摘要

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

1.c++中的虚函数
C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)和一个指向虚函数表的指针(vptr)来实现的。虚函数表,简称为vtbl,虚函数表表对实现多态起着至关重要的作用。在这个表中,主要保存了一个类中的虚函数的地址,这张表解决了继承、覆盖的问题,保证其内容能真实反应实际的函数。每一个包含虚函数的类的实例都包含一个cptr指针,指向虚函数表的首地址。我们可以通过这个指针找到要访问的虚函数的,完成虚函数的调用主要包括:找到虚函数表的首地址(vptr),通过cptr找到要使用虚函数地址,调用虚函数。那么使用虚函数大家总要考虑效率的问题,实际上为了提高效率,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()
{
    Base b;
    Fun pFun = NULL;
    cout << "虚函数表地址:" << (int*)(&b) << endl;
    cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
    pFun = (Fun)*((int*)*(int*)(&b));
    pFun();
    return 0;
}


通过这个示例,可以看到,通过强行把&b转成int *,取得虚函数表的地址(vptr),然后,再次取址就可以得到第一个虚函数的地址了,也就是Base::f(),这在上面的程序中得到了验证(把int* 强制转成了函数指针)。通过这个示例,我们就可以知道如果要调用Base::g()和Base::h(),其代码如下:

(Fun)*((int*)*(int*)(&b)+0); // Base::f()

(Fun)*((int*)*(int*)(&b)+1); // Base::g()

(Fun)*((int*)*(int*)(&b)+2); // Base::h()


可以看看虚函数表的图是怎么画的:

            

大家都知道,多态是通过继承实现的,那么我们要说说虚函数继承的问题。继承就涉及到了虚函数的覆盖了,实际上不被覆盖的虚函数和多态又有什么联系呢?这里我们讨论有覆盖的虚函数表是什么样的,假设存在下面的继承关系:

        

看看虚函数表示什么样的:

        

可以发现,Base::f()被覆盖了,这样若把Derive的实例赋值给一个基类Base指针pBase,通过pBase->f();则访问的是子类中的f()也就是完成了多态。那么虚函数表中的内容到底是怎么样的呢?可以看看下面的四句话就会明白!

1.虚函数按照其声明顺序放于表中。

2.父类的虚函数在子类的虚函数前面。

3.覆盖的f()函数被放到了虚表中原来父类虚函数的位置。

4.没有被覆盖的函数依旧。

2.用虚函数实现多态
看看下面的多态的代码:


#include <iostream>

using namespace std;

class Base
{
public:
    virtual void Print()
    {
        cout<<"Base::Print()"<<endl;
    }
};
class Derive : public Base
{
public:
    virtual void Print()
    {
        cout<<"Derive::Print()"<<endl;
    }
};
int main()
{
    Derive derive;
    Base *pBase = &derive;
    pBase->Print();
    return 0;
}
//多态代码


实现虚函数的代码,一定要切记:一定是基类的指针指向子类的对象的地址。首先试着理解一下用虚函数实现多态的原理,如果实在没理解为什么虚函数能实现多态,又为什么这样实现多态,上网再搜一搜相关的资料!!!

--结束END--

本文标题: 深入解析C++中的虚函数与多态

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 深入解析C++中的虚函数与多态
    1.C++中的虚函数C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类...
    99+
    2022-11-15
    虚函数 多态
  • 深入了解C++的多态与虚函数
    目录1.多态的机制与虚函数的机制1.1 多态的机制1.2 虚函数的机制1.3虚函数表的结构图1.4 动态多态实现的三个前提件(很重要)2.多态实例应用3.多态的巨大问题与虚析构3.1...
    99+
    2024-04-02
  • 深入解析C++中多态性和虚函数使用原理
    目录1.为什么需要virtual2.纯虚函数和抽象类3.构造函数与虚函数4.虚析构函数与纯虚析构函数5.纯虚析构函数的应用1.为什么需要virtual 按照Java的思维方式,在有了...
    99+
    2023-05-20
    C++ 多态性虚函数 C++ 多态性 C++ 虚函数
  • C++ 虚拟函数深入剖析:类型擦除与多态实现
    c++++虚函数实现多态,通过类型擦除将对象类型信息分离,使编译器仅识别公共接口。虚指针表存储虚函数地址,当基类指针指向派生类对象时,指向派生类虚指针表的派生类指针将替代基类指针指向的虚...
    99+
    2024-04-29
    c++ 虚拟函数
  • C++ 多态虚函数的底层原理深入理解
    目录1 多态的基本概念1.1 什么是多态1.2 怎么实现多态2 虚函数的底层原理1 多态的基本概念 1.1 什么是多态 多态是在不同继承关系的类对象,去调用同一函...
    99+
    2022-11-13
    C++ 多态虚函数底层原理 C++ 多态虚函数
  • C++的多态与虚函数你了解吗
    目录多态性虚函数总结多态性 多态性是面向对象程序设计的关键技术之一,若程序设计语言不支持多态性,不能称为面向对象的语言,利用多态性技术,可以调用同一个函数名的函数,实现完全不同的功能...
    99+
    2024-04-02
  • Python中的多态与虚函数
       C++中的虚函数与多态,是很多C++面向对象程序设计的一个基础,在Python中,是否也存在多态和虚函数,答案是有的。看下面的这个例子 from abc import ABCMeta, abstractmethod class...
    99+
    2023-01-31
    函数 多态 Python
  • C++的多态与虚函数是什么
    这篇文章主要介绍“C++的多态与虚函数是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++的多态与虚函数是什么”文章能帮助大家解决问题。多态性多态性是面向对象程序设计的关键技术之一,若程序设计...
    99+
    2023-06-29
  • C++虚函数表与类的内存分布深入分析理解
    目录不可定义为虚函数的函数将析构函数定义为虚函数的作用虚函数表原理继承关系中虚函数表结构多重继承的虚函数表多态调用原理对齐和补齐规则为什么要有对齐和补齐资源链接不可定义为虚函数的函数...
    99+
    2022-11-13
    C++ 虚函数表 C++ 类的内存分布
  • C++虚函数表与多态实例代码分析
    这篇文章主要介绍“C++虚函数表与多态实例代码分析”,在日常操作中,相信很多人在C++虚函数表与多态实例代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++虚函数表与多态实例代码分析”的疑惑有所帮助!...
    99+
    2023-07-05
  • C++学习之虚函数表与多态详解
    目录概述C++虚函数表指针和虚函数表C++ 虚函数表和多态概述 C++的多态在不同环境下实现方式可能不一样,虚函数表是C++实现多态的一种方式。 问题: 什么情况下C++会使用虚指针...
    99+
    2023-05-14
    C++虚函数表 多态 C++虚函数表 C++ 多态
  • C++的多态和虚函数实例分析
    这篇文章主要介绍了C++的多态和虚函数实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的多态和虚函数实例分析文章都会有所收获,下面我们一起来看看吧。一、C++的面试常考点阿里虽然是国内Java的第一...
    99+
    2023-06-29
  • C++ 虚拟函数与继承:理解多态继承中的奥秘
    虚拟函数和继承在面向对象编程中实现多态性:声明虚拟函数允许派生类重写基类方法,并根据对象的运行时类型调用。继承建立类层次,派生类可访问和扩展基类数据和方法。多态继承允许派生类从多个基类继...
    99+
    2024-04-28
    c++ 多态
  • C++虚函数和多态超详细分析
    目录1.什么是虚函数2.纯虚函数3.c++多态4.纯虚函数和ADT过程5.虚析构函数6.dynamic_cast类型转换7.成员函数指针 1.什么是虚函数 C++类中用virtual...
    99+
    2023-01-28
    C++虚函数和多态 C++虚函数 C++多态
  • C++类与对象深入之构造函数与析构函数详解
    目录对象的初始化和清理一:构造函数1.1:构造函数的特性1.2:构造函数的分类二:析构函数2.1:概念2.2:特性三:拷贝构造函数3.1:概念3.2:特性3.3:拷贝构造函数调用时机...
    99+
    2024-04-02
  • 深入解析lenb函数与len函数的区别
    深入解析lenb函数与len函数的区别,需要具体代码示例 在Python编程语言中,字符串是一种常见的数据类型,并且经常需要对字符串进行相关操作和处理。在字符串处理的过程中,我们经常会使用到获取字符串长度的功能。Python提供...
    99+
    2024-01-29
    len函数 lenb函数 区别分析
  • C++虚函数表深入研究
    目录探索虚函数表结构继承基类重写虚函数多基类继承 虚函数表寻找被覆盖的虚函数总结面向对象的编程语言有3大特性:封装、继承和多态。C++是面向对象的语言(与C语言主要区别),所以C++...
    99+
    2024-04-02
  • 详解C++虚函数中多态性的实现原理
    目录什么是虚函数多态性的实现多态的底层原理多态性的好处总结在面向对象的编程中,多态性是一个非常重要的概念。多态性意味着在不同的上下文中使用同一对象时,可以产生不同的行为。C++是一种...
    99+
    2023-05-19
    C++虚函数的多态性原理 C++虚函数 多态性 C++虚函数
  • C++中的多态问题—理解虚函数表及多态实现原理
    目录一、多态的概念概念构成条件二、虚函数的重写重写的定义重写的特殊情况override和final关键字区分重写、重载、重定义抽象类的概念三、多态的实现原理父类对象模型补充:生成默认...
    99+
    2023-02-05
    C++中的多态 C++虚函数表 C++多态实现原理
  • Pytorch中torch.stack()函数的深入解析
    目录一. torch.stack()函数解析1. 函数说明:2. 代码举例总结一. torch.stack()函数解析 1. 函数说明: 1.1 官网:torch.stack(),函...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作