C++ 虚函数的调用机制的初步探索,vptr/vtbl究竟在何处,请看:(Solstice)

陈硕 2001-11-20 09:50:04
C++ 虚函数机制的初步探索 ———— 在单(且non-virtual)继承下的虚函数调用
我发现,在Borland C++ Builder Compiler free 5.5.1下
若Base pb = new Derived;
则pb == vptr, 且vtbl == *pb, 第一个虚函数的入口地址是vtbl[0], 第二个是vtbl[1], 等等

请看以下程序:
#include <iostream>
using std::cout;
using std::endl;

class Base {
public:
virtual void zuu() { cout << "Base::zuu" << endl; }
virtual void foo() { cout << "Base::foo " << ", a = " << a <<endl; }
virtual void gaa(int c) { cout << "Base::gaa"<< ", a = " << a << ", c = " << c << endl; }
Base():a(123) { };
protected:
int a;
};

class Derived : public Base
{
public:
virtual void zuu(){ cout << "Derived::zuu" << endl; }
virtual void foo() { cout << "Derived::foo " << ", a = " << a << ", b = " << b << endl; }
Derived():b(456) { };
private:
int b;
};

void mycall_noPara(void *p, int n);
void mycall_int(void *p, int n, int para);

int main()
{
Base *pb = new Derived;
cout << "Derived object: \n";
pb->zuu(); //没有访问data member
pb->foo(); //访问data member
pb->gaa(1982); //访问datamember和argument
cout << "\nDirectly invoke the virtual functions : \n" ;
mycall_noPara(pb, 0);
mycall_noPara(pb, 1);
mycall_int(pb, 2, 1982);

delete pb;
pb = new Base;

cout << "\n\nBase object: \n";
pb->zuu();
pb->foo();
pb->gaa(1982);
cout << "\nDirectly invoke the virtual functions : \n" ;
mycall_noPara(pb, 0);
mycall_noPara(pb, 1);
mycall_int(pb, 2, 1982);

delete pb;
}

void mycall_noPara(void *vptr, int n)
{
typedef void (*VTBL)(); // Virtual Table
typedef void (*PFV)(void*); // Pointer to Function with parameter (void*)
VTBL *vtbl = (VTBL*)*(int*)vptr; // dereference the vptr, initialize vtbl
PFV pfv = (PFV)vtbl[n]; // 得到第n个 Virtual Function's address
pfv(vptr); // consider p as the "this" pointer, invoke the function
}

void mycall_int(void *vptr, int n, int para)
{
typedef void (*VTBL)();
typedef void (*PFVI)(void*, int); // Pointer to Function with parameter (void*, int)
VTBL *vtbl = (VTBL*)*(int*)vptr; // dereference the vptr, initialize vtbl
PFVI pfvi = (PFVI)vtbl[n]; // 得到第n个 Virtual Function's address //小弟英语不够好
pfvi(vptr, para); // consider p as the "this" pointer, invoke the function
}

侯先生在《C++ 的沉迷与爱恋》一文中的建议:
----- 引用 -----
●不要沉迷於 C++ semantics 和 C++ object model

对於底层知识有浓厚兴趣的朋友,下探到 object model 领域,一定会非常开心地在 object size、object layout、vptr/vtbl、以及许多布幕後的技术之间玩将起来。了解这些东西,当然是好的,但是由於一探究竟得其奥秘的快感与成就感,使得一些朋友们在这个层面里「玩」起来了,小地方玩得很精,玩得不亦乐乎,玩得忽略了 C++/OOP 的最终目标。

最终目标是 polymorphism!

我要说,在 C++ syntax 以及相对低阶的 C++ semantics 里,不要玩得太过火。过犹不及,会伤身的。

----- 引用完 -----

牢记侯Sir的教导!
...全文
284 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
陈硕 2001-11-22
  • 打赏
  • 举报
回复
配合图形就会容易理解了。
darkay 2001-11-22
  • 打赏
  • 举报
回复
不知道想表达什么意思,你的语文水平真是差啊!
LANDFISH 2001-11-20
  • 打赏
  • 举报
回复
YUP
内容概要:本文档围绕基于MATLAB/Simulink平台的直流无刷电机速度控制系统展开,重点介绍利用Simulink搭建电机控制模型,实现直流无刷电机的速度开环控制仿真。文档详细阐述了系统建模、关键模块设计与参数配置过程,帮助读者深入理解电机控制的基本原理与仿真流程。同时,文档还列举了涵盖电力电子、新能源系统、路径规划、智能优化算法等多个领域的丰富仿真案例,充分展示了MATLAB/Simulink在多学科交叉科研仿真中的强大功能与广泛应用前景。; 适合人群:具备一定自动控制理论基础和MATLAB/Simulink使用经验的高校学生、科研人员及工程技术人员,特别适用于从事电机控制、电力电子、新能源系统、智能优化等方向的研究者。; 使用场景及目标:①学习直流无刷电机的工作原理及其速度开环控制方法;②掌握使用Simulink进行电机控制系统建模与仿真的核心技能;③为后续开展更高级的闭环控制、矢量控制或结合智能优化算法的电机控制研究奠定坚实的技术基础并提供实用的参考实例。; 阅读建议:建议读者结合文档提供的仿真模型与代码资源,亲自动手实践Simulink建模全过程,逐步理解各功能模块的作用与参数整定方法,并充分利用网盘中的配套资料进行复现与深入学习,从而有效提升科研仿真与工程实践能力。
内容概要:本文系统阐述了基于二维离散时间卡尔曼滤波器在二维平面内对运动目标进行轨迹跟踪的技术方案,重点分析了过程噪声与测量噪声在不同强度下对滤波性能的影响。通过建立目标状态空间模型,设计完整的预测与更新算法流程,实现了对受噪声干扰的观测数据进行有效估计与轨迹平滑,充分展现了卡尔曼滤波在动态系统状态估计中的鲁棒性与实用性,并提供了完整的Matlab代码实现,便于理论验证与参数调试。; 适合人群:具备信号处理、控制理论或状态估计基础知识的研究生、科研人员,以及从事雷达系统、导航定位、机器人感知、自动驾驶等领域的工程技术人员。; 使用场景及目标:① 掌握卡尔曼滤波的核心原理及其在目标跟踪中的建模与实现方法;② 分析不同噪声协方差参数对滤波收敛性、估计精度和平滑效果的影响;③ 为深入研究非线性滤波算法(如EKF、UKF)或多传感器融合技术奠定理论与实践基础。; 阅读建议:建议读者结合所提供的Matlab代码进行仿真实验,通过调整过程噪声和观测噪声的强度,观察滤波轨迹与真实轨迹的偏差变化,深入理解协方差矩阵的演化机制,并尝试将该方法拓展至三维空间或多目标跟踪场景,以增强实际应用能力。

70,038

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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