访问基类的私有虚函数 "*((int*)*(int*)(&b)+i)"

jinghuaboy 2014-03-22 03:16:24
#include <iostream>

using namespace std;

class Base
{
virtual void g()
{
cout << "Base::g" << endl;
}
virtual void f()
{
cout << "Base::f" << endl;
}
};
class Derived:public Base
{
void g()
{
cout << "Derived::g" << endl;
}
virtual void h()
{
cout << "Derived::h" << endl;
}
};

typedef void (* Fun)(void);

int main(void)
{
Derived d;
Fun pFun = NULL;
for (int i = 0; i < 3; ++i)
{
pFun = (Fun)*((int *)*(int *)(&d) + i);
pFun();
}
return 0;
}

VS2010环境下运行结果:
Derived::g
Base::f
Derived::h

结论:
1: 应该有假设“指向虚函数表vtable的虚函数表指针vt_ptr位于位于对象内存块的开始处”;
2: (Fun)*((int *)*(int *)(&d) + i): (将指针当做地址)
(&d): 获得对象d的地址addr1,此地址对应整个对象d的内存块;
(int*)(&d): 将Derived类型地址addr1强制转换为int类型地址addr2,此地址对应的内存块即为vt_ptr变量;
*(int*)(&d): 取int类型地址addr2对应内存块中的值,得int类型值val1,该值其实为虚函数表的首地址;
(int*)*(int*)(&d): 将int类型值val1强制转换为int类型地址addr3,该值即为虚函数表vtable的首地址;
((int*)*(int*)(&d)+i): 对int类型地址addr3进行算术加,得到虚函数表中元素i的地址addr_i;
*((int*)*(int*)(&d)+i): 取int类型地址addr_i对应内存块中的值的int类型值val_i,该值其实为虚函数表中元素i中存储的对应的虚函数的指针;
(Fun)*((int *)*(int *)(&d) + i): 将int类型值val_i强制转换为Fun类型地址(指针);

论证:
上述讨论中将指针看做地址,其实指针和地址应该是等效的:
int a = 0xAAAABBBB;
int *b = &a;
对以上两个定义语句,a和b都有自己的内存块,假设对应地址值分别为addr_a和addr_b。
则当执行表达式(int *)*b时,意思是将地址值addr_b对应内存块中存储的值(即为地址值addr_a)所对应的内存块中的值0xAAAABBBB强制转换为int*(即int类型指针,也即int类型地址)。

讨论:
不知这样理解是否正确?
...全文
363 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinghuaboy 2014-03-27
  • 打赏
  • 举报
回复
引用 6 楼 unituniverse2 的回复:
“不同编译器对虚函数表的支持也是有差别的也是知道的” 有些编译器对虚函数的实现中根本没有虚表
虚函数实现跟编译器有关。最近在看一些面试题,各种奇葩问题,比较疑惑。
unituniverse2 2014-03-22
  • 打赏
  • 举报
回复
“不同编译器对虚函数表的支持也是有差别的也是知道的” 有些编译器对虚函数的实现中根本没有虚表
Walle_Oyq 2014-03-22
  • 打赏
  • 举报
回复
个人感觉是奇技淫巧,实际上编程基本上不会用到,当然你要用也没人说。
jinghuaboy 2014-03-22
  • 打赏
  • 举报
回复
引用 1 楼 taodm 的回复:
等你多试几种编译器,多试几种继承模式后,再说吧。 讨论这东西就是浪费生命的。
我只是想问在本问题设定的条件下,对结论(2)中 “(Fun)*((int *)*(int *)(&d) + i)”的理解是否合理、正确。 其他几种继承模式是知道的,不同编译器对虚函数表的支持也是有差别的也是知道的。
lm_whales 2014-03-22
  • 打赏
  • 举报
回复
引用 1 楼 taodm 的回复:
等你多试几种编译器,多试几种继承模式后,再说吧。 讨论这东西就是浪费生命的。
++
jinghuaboy 2014-03-22
  • 打赏
  • 举报
回复
我只是想问在本问题设定的条件下,对结论(2)中 “(Fun)*((int *)*(int *)(&d) + i)”的理解是否合理、正确。 其他几种继承模式是知道的,不同编译器对虚函数表的支持也是有差别的也是知道的。
taodm 2014-03-22
  • 打赏
  • 举报
回复
等你多试几种编译器,多试几种继承模式后,再说吧。 讨论这东西就是浪费生命的。
内容概要:本文介绍了一种基于PSO-RNN-GAN混合智能算法的无人机三维路径规划模型,结合粒子群优化算法(PSO)的全局搜索能力、循环神经网络(RNN)的时序建模优势以及生成对抗网络(GAN)的路径生成能力,在MATLAB平台上实现了复杂三维环境中高效、平滑、低能耗且具备动态避障能力的路径规划系统。文中详细阐述了模型架构,包括三维环境建模、PSO路径搜索、RNN路径平滑、GAN路径创新生成、多目标损失优化及自适应调度机制,并提供了关键模块的代码示例与仿真可视化方法,支持多无人机协同扩展,具备良好的泛化性与工程应用前景。; 适合人群:具备一定机器学习与优化算法基础,从事无人机导航、智能控制、路径规划相关研究或开发工作的科研人员与工程师,尤其适合研究生、算法研发人员及自动化、航空航天领域从业者; 使用场景及目标:①应用于复杂三维环境下的无人机自主导航路径规划,实现高效避障与节能飞行;②为动态障碍、多目标优化、路径平滑性与动力学约束等问题提供综合性解决方案;③作为智能交通、多智能体协同、自动驾驶等领域路径决策系统的参考模型; 阅读建议:此资源以MATLAB实现为核心,包含模型设计与部分代码,建议读者结合文中架构图与代码片段搭建仿真环境,逐步复现并调试各模块功能,重点关注多算法融合机制与损失函数设计,深入理解PSO、RNN、GAN在路径规划中的协同作用。
内容概要:本文介绍了一种基于两阶段鲁棒优化算法的微网多电源容量配置方法,并提供了完整的Matlab代码实现。该方法针对微电网中风能、光伏、储能等多种分布式电源的容量规划问题,充分考虑了可再生能源出力与负荷需求的不确定性,通过构建两阶段鲁棒优化模型,在第一阶段确定电源的最优配置容量,在第二阶段应对实际运行中的不确定因素,从而提升系统运行的经济性与可靠性。文中详细阐述了模型构建过程、不确定性集合的设定、列与约束生成(C&CG)算法的求解流程,并结合算例验证了所提方法的有效性和鲁棒性。; 适合人群:具备一定电力系统基础知识和Matlab编程能力,从事微电网、综合能源系统、可再生能源集成等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习和掌握两阶段鲁棒优化理论在电力系统规划中的具体应用;② 理解并复现微网多电源容量配置的建模与求解全过程;③ 将该方法迁移应用于类似的能源系统优化问题,如储能配置、配电网络规划等。; 阅读建议:建议读者结合Matlab代码逐行理解算法实现细节,重点关注不确定性建模与C&CG算法的迭代求解过程,有条件者可尝试修改算例参数或引入新的电源类型以深化理解和应用能力。

65,209

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧