虚基类 成员变量 访问

BBAPI 2011-09-21 09:02:45
如:

class A
{
int a;
};
class B:virtual public A
{
int b;
};
class C:virtual public A
{
int c;
};
class D:public B,public C
{
int d;
};

请知道的坛友描述下派生类D的对象访问虚基类成员变量如a的过程,我只知道有个虚表,可至于如何获取虚表,虚表存取的是什么,虚表存在B,C,还在D?
...全文
199 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
BBAPI 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 chos2006 的回复:]

事实上,虚函数表的指针是放在对象的最前面的位置,比如:
C/C++ code

class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "……
[/Quote]
多谢回复
chos2006 2011-09-22
  • 打赏
  • 举报
回复
事实上,虚函数表的指针是放在对象的最前面的位置,比如:

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

我们可以通过Base的实例来得到虚函数表。操作如下:

typedef void(*Fun)(void);
Base b;
Fun pFun = NULL;

// 调用虚函数f
pFun = (Fun)*((int*)*(int*)(&b)+0);
pFun();

// 调用虚函数g
pFun = (Fun)*((int*)*(int*)(&b)+1);
pFun();

// 调用虚函数h
pFun = (Fun)*((int*)*(int*)(&b)+2);
pFun();

这样调用后的输出情况如下:
Base::f
Base::g
Base::h

有继承的情况下,可以通过子类的实例来访问其虚函数表,不过在有覆盖的情况下,真正调用的是子类的函数,这样也就实现了多态。

class Derive : public Base
{
virtual void f() { cout << "Derive::f" << endl; }
virtual void g1() { cout << "Derive::g1" << endl; }
virtual void h1() { cout << "Derive::h1" << endl; }

};

实例Base b的虚函数表为:
Base::f()-->Base::g()-->Base::h()
实例Derive d的虚函数表为:
Derive::f()-->Base::g()-->Base::h()-->Derive::g1()-->Derive::h1()
请注意这里第一个为子类Derive的成员f(),而不是Base的。
BBAPI 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 q191201771 的回复:]

想要探寻本质, 先搞清楚 单一继承时 多态 是如何实现的

不然的话你只要知道虚拟继承的作用、多态的使用方法就OK了
[/Quote]
嗯,不过如果可以的话麻烦解决下我的问题。
BBAPI 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 radiohead001 的回复:]

哦,这一节

3.4 Inheritance and the Data Member
[/Quote]
多谢
就想叫yoko 2011-09-22
  • 打赏
  • 举报
回复
想要探寻本质, 先搞清楚 单一继承时 多态 是如何实现的

不然的话你只要知道虚拟继承的作用、多态的使用方法就OK了
radiohead001 2011-09-22
  • 打赏
  • 举报
回复
哦,这一节

3.4 Inheritance and the Data Member
radiohead001 2011-09-22
  • 打赏
  • 举报
回复
虚拟继承用于菱形继承,这样D类中只含有一份A的实例。至于虚表的实现,各个编译器的实现方式都不一样,我是不太清楚了。真想了解的话,看看深入理解C++对象模型吧,讲得很细。
小小蔷薇 2011-09-22
  • 打赏
  • 举报
回复
关注!!!!!
BBAPI 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hui12345685 的回复:]

D的对象多继承于B和C,虽然B和C都继承有A的一部分,但是D只有一分A类的的信息。这就是虚继承的作用。
你想要看到虚表的话在vc下调试可以很清晰的看的到。
虚表指针其实就是一直指针指向了vtable,然后里面存放的只虚函数的地址,虚表是存在于B,C和D。A如果有虚函数才有续表
[/Quote]
可sizeof(D) == 24 "虚表是存在于B,C和D"???
hui12345685 2011-09-21
  • 打赏
  • 举报
回复
D的对象多继承于B和C,虽然B和C都继承有A的一部分,但是D只有一分A类的的信息。这就是虚继承的作用。
你想要看到虚表的话在vc下调试可以很清晰的看的到。
虚表指针其实就是一直指针指向了vtable,然后里面存放的只虚函数的地址,虚表是存在于B,C和D。A如果有虚函数才有续表
BBAPI 2011-09-21
  • 打赏
  • 举报
回复

65,208

社区成员

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

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