问个虚函数向基类指针转换的问题

zwd2005 2009-12-27 06:17:45
((B*)(A*)p)->foo(0); 这一句的结果没理解

#include <iostream>

using namespace std;

class A {
public:
virtual void foo(int*) = 0;
};

class B {
public:
virtual void foo(double*) = 0;
};

class C: public A, public B {
public:
void foo(double*) {
cout << "double" << endl;
}

void foo(int*) {
cout << "int" << endl;
}
};

int main() {
C* p = new C();
void* vp = p;
((B*)p)->foo(0); // double
((B*)(A*)p)->foo(0); // int # why not double ?
((B*)(C*)p)->foo(0); // double
return 0;
}

...全文
90 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
周成风 2009-12-27
  • 打赏
  • 举报
回复
建议换个函数名字!!!!!
机智的呆呆 2009-12-27
  • 打赏
  • 举报
回复
C* p = new C();
p指向对象有两部分组成,低地址部分区域是A对象区域,其后是B对象的区域
p指向对象里有两个虚表指针,其中(int*)p~(int*)p+1这四个字节里是指向A类虚表的指针,因为A类中没有成员变量,所以现在随后四个字节是指向B类虚表的指针。
((B*)p)->foo(0);
由于p所指向的内存布局中低地址不符是A类的对象布局,其后的高地址才是B类对象的布局,当以(B*)类型的解析p指向的内存区域时,返回的是p指向的内存区域中偏移Sizeof(A)后的地址,既C对象中B对象部分。随后通过查p指向内存布局中b对象部分的虚表指针,调用到B中foo函数。
((B*)(A*)p)->foo(0);
(A*)p返回的C对象中A对象部分,((B*)(A*)p)把A对象部分当B对象来解析,B调用foo也是需要查询虚表的,于是把指向A的虚表指针,当成指向B的虚表指针来用,结果查出的是A中foo函数。




macrojj 2009-12-27
  • 打赏
  • 举报
回复
我认为如果是虚函数的调用 都应该是通过虚表进行的。
zwd2005 2009-12-27
  • 打赏
  • 举报
回复
vs2008上时编译通过的,正常运行。g++上没试。
(B*)(A*)p, 我理解的就是一个指针,最后被准成B*了呗,但运行出来是int,就不理解了
dskit 2009-12-27
  • 打赏
  • 举报
回复
((B*)(A*)p)->foo(0);// 这样转,让编译器情何以堪啊?
dskit 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用楼主 zwd2005 的回复:]
((B*)(A*)p)->foo(0); 这一句的结果没理解
C/C++ code
#include<iostream>usingnamespace std;class A {public:virtualvoid foo(int*)=0;
};class B {public:virtualvoid foo(double*)=0;
};class C:public A,public B {public:void foo(double*) {
cout<<"double"<< endl;
}void foo(int*) {
cout<<"int"<< endl;
}
};int main() {
C* p=new C();void* vp= p;
((B*)p)->foo(0);// double ((B*)(A*)p)->foo(0);// int # why not double ? ((B*)(C*)p)->foo(0);// doublereturn0;
}
[/Quote]

((B*)p)->foo(0);这样转,让编译器情何以堪啊?
arong1234 2009-12-27
  • 打赏
  • 举报
回复
不理解就对了,这种转换我个人认为是有问题的

64,654

社区成员

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

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