通过指针访问虚函数表调用函数

C++中通过指针调用虚函数 阅读详情
环境: VS2019, Debug x86编译器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class Base {
public:
	virtual void func1() = 0;
	virtual void func2() = 0;
};

class Drived : public Base {
public:
	virtual void func1()
	{
		printf("Drived::%s()\n", __func__);
	}

	virtual void func2()
	{
		printf("Drived::%s()\n", __func__);
	}
};

typedef void(*Fun)();

int main()
{
	Base* pBase = new Drived();

	pBase->func1();
	
	// printf("sizeof(long) = %zu\n", sizeof(long));
	printf("0x%p\n", pBase);
	printf("0x%p\n", (int*)pBase);
	int ptr = (*(int*)pBase); // vfptr的地址
	Fun pF = (Fun)(*((int *)ptr + 1));
	pF();

	delete pBase;
	return 0;
}

运行结果:
在这里插入图片描述

如果是在x64编译器环境下则把int *换成long long *, 因为两者的偏移量不一致
我在x64环境下long的字节为4

__vfptr是函数指针数组,在x64下指针是8个字节,所以vfptr数组内的元素各占8字节,故需要使用long long指针,这样+1才会偏移8个字节,如果为int *,则+1偏移量是4

下面是传参函数环境与上一致

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class Base {
public:
	virtual void func1() = 0;
	virtual void func2(int num) = 0;
};

class Drived : public Base {
public:
	virtual void func1()
	{
		printf("Drived::%s()\n", __func__);
	}

	virtual void func2(int num)
	{
		printf("Drived::%s(%d)\n", __func__, num);
	}
};

typedef void(__stdcall *Fun)(int); 
// 不太理解此处为何需要加stdcall
// 参考https://blog.youkuaiyun.com/sky1718/article/details/51004758加上后运行不报错了

int main()
{
	Base* pBase = new Drived();

	pBase->func1();
	
	// printf("sizeof(long) = %zu\n", sizeof(long));
	// printf("0x%p\n", pBase);
	printf("0x%p\n", (int *)pBase);
	int ptr = (*(int *)pBase);
	Fun pF = (Fun)(*((int *)ptr + 1));
	pF(10);

	delete pBase;
	return 0;
}

运行结果:
在这里插入图片描述

题外话

如果把Base的public改为private,那么使用vfptr仍然可以调用到private的函数
如果你只是把Drived的public改为private,则pBase->func1()不会报错,因为func1继承过来的就是public

【面经笔记】虚函数表指针个数 本文参考了 http://www.cnblogs.com/jerry19880126/p/3616999.html 上述博客给出了以下结论: 每个类都有虚指针和虚表; 如果不是虚继承,那么子类将父类的虚指针继承下来,并指向自身的虚表(发生在对象构造时)。有多少个虚函数,虚表里面的项就会有多少。多重继承时,可能存在多个的基类虚表与虚指针; 如果是虚继承,那么子类会有两份虚指针,一份指向自己的虚表, 阅读详情

相关推荐

通过虚函数表调用虚函数与通过虚函数表(绕过访问权限控制)

一、背景知识           在讲解虚函数的时候,我们知道,如果类中有虚函数,则该类中存在一个虚函数表(V-Table),每个该类的对象都会有一个指针指向该虚函数表,存储这类中虚函数的函数指针,而虚函数表的地址就存在该类对象内存的开始处,目的是为了方便查找虚函数。         在陈浩的技术专栏中写过一篇对C++虚函数表解析很透彻的的文章: C++ 虚函数表解析

IIcyZhao's Road 4365

虚函数表解析

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

yangshuangtao的专栏 597

通过虚函数表访问私有成员函数

函数指针的使用 有一些C/C++编程经验的同学应该都知道,函数指针这个概念:函数指针,即指向一个函数的指针,我们可以通过函数指针来访问一个函数,这时函数可以像对象一样使用,比如用于函数参数,比如使用数组对函数指针进行存储;如下是函数指针使用的一个实例。 #include "stdafx.h" #include <iostream> void func1() { std::co...

qq_28204903的博客 682

C++调用虚函数是如何确定是虚函数表中的哪一项?

class Base { public: virtual func1() {}; virtual func2() {}; } class Child : public Base { public: virtual func1() {}; virtual func3() {}; } Base* b = new Child(); b->func1(); 要讨论的是 `b->func1()`编译器以及运行时是怎么操作的 先说结论: 1.编译器会给每个虚函数指定一个在虚函数表中的索引 ...

qq_39025293的博客 855

群晖NAS断电后IP变了?3步搞定静态IP设置(附Linux挂载指南)

本文针对群晖NAS因断电重启导致IP地址变化的问题,提供了从根源到实践的完整解决方案。核心内容包括如何为NAS配置静态IP以彻底解决连接中断,并详细讲解了在Linux系统中通过NFS协议稳定挂载NAS共享文件夹的步骤与指南,确保网络存储服务持久可靠。

weixin_29271263的博客 851

CodeBuddy 接入 MCP,一键生成网站!

2024 年 11 月,Anthropic 公司搞了个挺有意思的新玩意 - Model Context Protocol(模型上下文协议)简称为 MCP 协议。简单来说,它就是给 AI 和各类工具数据之间搭了个标准化的”桥梁”,让开发者不用再为对接问题头疼了。mcp.so如下图所示,这是 mcp.so 网站中的 MCP Server。使用百度/高德地图分析旅线计算时间接 Puppeteer 自动操作网页使用 Github/Gitlab 让大模型接管代码仓库。

悟空聊架构的专栏 1945

C++之虚函数

C++之虚函数 介绍 首先要明白什么是虚函数,函数名称前面加上virtual这个函数就称为虚函数,常用在继承关系里,子类想要修改父类的某个函数,就将父类对应的函数声明为虚的。 非虚函数:普通函数,你不希望子类重新定义(重写)它 虚函数:你希望子类重新定义它,并且它已经有默认定义 纯虚函数:你希望子类一定重新定义它,你对他没有默认定义。 如下程序: class Shape{ public: virtual void draw()const=0;//纯虚函数 virtual void error(c

qq_44559016的博客 265

某银行大数据分析平台之云原生架构

软考架构师论文

doudoudouy的博客 768

C++ 虚函数表指针以及虚函数指针的确定

【摘要】 很多教材上都有介绍到虚指针、虚函数与虚函数表,有的说类对象共享一个虚函数表,有的说,一个类对象拥有一个虚函数表;还有的说,无论用户声明了多少个类对象,但是,这个VTABLE虚函数表只有一个;也有的在说,每个具有虚函数的类的对象里面都有一个VPTR虚函数指针,这个指针指向VTABLE的首地址,每个类的对象都有这么一种指针。今天,我们就来解决这个问题,同一个类的不同对象,是不是拥有“相同”...

JackZhangNJU的专栏 3126

ATR2660:卫星导航高增益低噪声放大器芯片数据手册

中国BDS(北斗卫星导航系统),美国的GPS,俄罗斯的GLONASS和欧盟的GALILEO导航系统应用而专门设计。芯片支持3.3V至5V宽电源供电。采用2级放大器的结构设计,具有28dB高增益和0.85dB的低噪声系数。支持BDS、GPS、GALILEO、GLONASS等L。典型功率增益:30dB@5V;典型输入P1dB:-18dBm@3.3V;典型工作电流:12.7mA@3.3V;宽供电电压范围:3.3V~5V;典型噪声系数:0.85dB;频段的多个卫星导航系统;ATR2660是一颗。

YHPsophie的博客 561

S4HANA Rebate Management(条件合同) -Single Step

S4HANA 条件合同管理(Condition Contract Management), 包括如何创建条件合同,场景应用

m0_50200150的博客 2307

C++函数指针与虚函数指针对私有虚函数进行访问

C++函数指针与虚函数指针对私有虚函数进行访问虚函数表与虚函数指针函数指针通过虚函数表指针访问虚函数 虚函数表与虚函数指针 (图片来自侯捷老师) 虚函数表的首地址即为类对象的起始地址存放的指针,该指针即为虚函数表指针,指向虚函数表 虚函数表中每一项都是一个指向虚函数地址的指针,非虚函数不在表中 函数指针 它其实就是一个特殊的指针,它用于指向函数被加载到的内存首地址,可用于实现函数调用。听上有点像函数名,函数名也是记录了函数在内存中的首地址,加()就可以调用。 函数指针就是一种特殊的指针。 如果

lzh824359508的博客 681

创建 Qt Quick 项目

来看看如何使用 Qt Creator 创建 Qt Quick 项目!

青春不老,奋斗不止! 1万+

C中访问基类的私有虚函数的方法是什么?

在C++中,访问基类的私有虚函数并不是一件直接的事情,因为私有成员函数的访问权限限制了其在派生类中的直接访问。- `student`类继承自`person`,并重写了`name()`函数,还添加了两个新的虚函数`address()`和`ID()`。- `person`类包含一个公共虚函数`name()`和一个私有虚函数`sex()`。2. **访问虚函数表中的函数指针**:通过虚函数表指针可以访问其中的函数指针。1. **获取对象的虚函数表指针**:通过对象的地址可以获取其虚函数表指针。

wang15510689957的博客 627

YOLO26 正式发布源代码!极致速度优化方案, 面向工业级落地的目标检测模型!

YOLO26 作为 Ultralytics 公司于 2025 年 9 月发布的最新一代目标检测模型,在架构设计和技术实现上展现了显著的创新。本文深入分析了 YOLO26 的核心架构改进和技术原理,重点探讨了其在边界框回归、推理流程、损失函数设计和优化算法方面的突破性进展。

魔改工程师的博客 1243

如何用DeepSeek写年底工作总结?——从入门到精通的全流程指南

AI助手DeepSeek如何高效撰写工作总结 摘要:本文介绍如何利用DeepSeek智能AI助手高效完成工作总结写作。工作总结具有结构固定、语言规范、内容数据化三大特性,而DeepSeek的结构化生成、风格适配、数据整合和迭代优化四大核心能力与之完美匹配。文章提出"准备-搭架-填充-优化"四步工作法:1)精准输入岗位、时间范围等核心信息;2)先搭建逻辑清晰的提纲框架;3)分模块填充具体内容,突出数据与案例;4)通过风格润色和细节补充进行优化。通过合理运用多模态材料处理能力,DeepSee

通俗易懂学IT 287

C++ 虚函数表解析

为什么80%的码农都做不了架构师?>>> ...

weixin_34380781的博客 68

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++ 多态学习笔记(下)

开始新的学习之前,我们先通过一段涉及继承、多态的 代码来回忆、加深理解。Animal作为基类,我们要给每种动物实例化出sound()的模块,因为Animal在实际意义上没什么好实例化的,所以设计成抽象类。虽然Animal不能实例化出对象,,来作为的条件。这里的Animal就是作为一个像工具人一样的类,本身就不打算实例一个Animal,因为必须要指定出具体是什么动物之后,sound()这个函数才有意义。

2301_79501467的博客 1288

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C++虚函数多态

本文主要探讨C++中虚函数和多态的实现机制。当类中包含虚函数时,编译器会生成虚函数表(vtbl)和虚函数表指针(vptr),vptr通常占用8字节空间。多态发生的核心条件必须同时满足:通过基类指针/引用调用虚函数,且派生类重写了该虚函数。文中通过代码示例展示了多态的应用场景,并强调虚析构函数的重要性,指出若不声明为虚函数可能导致派生类资源泄漏。文章还分析了多继承情况下的vptr处理机制,总结出多态性的核心逻辑在于虚函数重写、基类访问派生类对象以及通过基类接口调用函数。

hhxxyz的博客 351

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

继承&多态中的父类引用子类对象问题

继承中要1.必须通过基类的指针或者引用调用虚函数2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写当我们在父类和子类中定义了一个都一样的函数时,我们可以说这两个函数构成隐藏(重定义),而如果在父类这个函数前面加一个那么这两个函数则构成在使用父类指针或引用这个子类对象调用该函数时,则会构成多态;

zzxz8的博客 257

c++中虚函数,虚函数表,虚函数表指针

在C++中随处可见封装,继承,多态。多态的实现,是基于虚函数的继承,虚函数则是基于虚函数表和虚函数表指针。用一个示例介绍虚函数表指针访问虚函数,更易于方便理解虚函数,程序中也有注释// virtual-Table.cpp #include &lt;iostream&gt; using namespace std; class A { public: A() { cout &lt;&lt...

linux 1679

图解C++多态,虚函数、虚函数表、虚指针、重写与覆盖

多态         多态就是多种形态,C++的多态分为静态多态与动态多态。         静态多态就是编译器根据函数实参的类型判断出要调用哪个函数。比如函数重载和函数模板。         动态多态依靠的是虚函数表和动态绑定机制,因为是在运行时根据对象的类型在虚函数表中寻找调用函数的地址来调用相应的函数,所以称为动态多态。         本文仅

WYuan的博客 2461

如何通过指针访问虚函数表,并且调用里面的方法

昨天面头条,,,最后面试官问道如何用指针访问虚函数表的东西。。。然后瞎写了一通,gg了应该。 昨天的答案 fun = (Fun)((int)(((Base*)0)->f)+4); fun() 额。。。。昨天的代码是编译也通不过的。。。因为C++是无法获取 任何方法地址的。。。简单的demo测试。。。 #include <iostream> ...

a450972459的博客 665

C++中虚继承产生的虚基类指针和虚基类表,虚函数产生的虚函数指针和虚函数表

本博客主要通过查看类的内容的变化,深入探讨有关虚指针和虚表的问题。 一、虚继承产生的虚基类表指针和虚基类表 如下代码:写一个棱形继承,父类Base,子类Son1和Son2虚继承Base,又来一个类Grandson继承Son1和Son2。 代码: class Base { public: int a; protected: int b; private: int c; }; class Son1 :virtual public Base { public: int a; protected: i

yi_chengyu的博客 8581

揭秘C++多态——父类指针如何正确调用函数?

你真的理解父类指针是如何调用函数的吗? 在C++的世界里,多态(Polymorphism)是面向对象编程的三大支柱之一。我们常常写下这样的代码: Base* ptr = new Derived(); ptr->virtualFunction(); 看似简单的一行调用,背后却隐藏着 this 指针、虚函数表(vtable)、动态绑定等精巧的机制。为什么父类指针能调用子类的实现?它又是如何“找到”正确函数的?this 指针在这个过程中扮演了什么角色?

大四在找工作,如果公司有需要的可以联系我13086825462@163.com 1359

虚函数表指针,虚函数表

虚函数表 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。 在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其内容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了 这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重

LEAKERS_ZZW的专栏 4235
上一篇: 字符串类String8
下一篇: P2P流程(一)
山有木兮啊
博客等级 码龄8年 135粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值