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的教导!
...全文
155 3 打赏 收藏 举报
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
陈硕 2001-11-22
配合图形就会容易理解了。
  • 打赏
  • 举报
回复
darkay 2001-11-22
不知道想表达什么意思,你的语文水平真是差啊!
  • 打赏
  • 举报
回复
LANDFISH 2001-11-20
YUP
  • 打赏
  • 举报
回复
发帖
C语言
加入

6.6w+

社区成员

C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
申请成为版主
帖子事件
创建了帖子
2001-11-20 09:50
社区公告
暂无公告