返回信息流#include <iostream>
using namespace std;
class A
{
public:
void fun(){cout<<"A"<<endl;}
};
class B:public A
{
public:
void fun(){cout<<"B"<<endl;}
};
void main()
{
A* pa=new A();
pa->fun();
B* pb=(B*)pa;
pb->fun();
delete pa,pb;
pa=new B;
pa->fun();
pb=(B*)pa;
pb->fun();
}
这个程序输出是AABB,若将两个virtual去掉,输出是ABAB。问题如下:
1)后者常解释为根据指针类型来调用,为什么前者就不能这么理解?
2)pb=(B*)pa;牵扯到虚函数的工作原理,最终根据指针指向的对象的vfptr来找对应的虚函数表是吗?是的话,第一个输出就明白了。
3)关于对象指针的强制类型转换,转换前后有什么异同吗?比如讲pa(指向A的对象)转换成B*后为什么就能调用到B的方法了?太奇怪了
这是一条镜像帖。来源:北邮人论坛 / cpp / #74868同步于 2013/10/28
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
被类对象的指针和虚函数搞晕了,求教
Mulany
2013/10/28镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
带virtual 的是覆盖吧,虚函数指针内容决定,不带virtual为隐藏,按地址寻址。
gdb看下变量的内存存储格式吧
【 在 Mulany 的大作中提到: 】
: #include <iostream>
: using namespace std;
: class A
: ...................
解决这里的困惑需要:
1. 理解多态的实现,基类指针或引用通过运行时绑定的具体对象来确定调用哪一个overrided函数。
2. 理解为什么从没有虚函数的基类到派生类的转型是危险的和dynamic_cast的使用场景。
3. 了解C++对象内存布局,这个可以解决你题目中的疑问,可以参考:
http://blog.csdn.net/haoel/article/details/3081328
【 在 Mulany 的大作中提到: 】
: #include <iostream>
: using namespace std;
: class A
: ...................
嗯,我先看看链接
【 在 rollse 的大作中提到: 】
: 解决这里的困惑需要:
: 1. 理解多态的实现,基类指针或引用通过运行时绑定的具体对象来确定调用哪一个overrided函数。
: 2. 理解为什么从没有虚函数的基类到派生类的转型是危险的和dynamic_cast的使用场景。
: ...................
这个回答的很专业,赞rollse
【 在 rollse 的大作中提到: 】
: 解决这里的困惑需要:
: 1. 理解多态的实现,基类指针或引用通过运行时绑定的具体对象来确定调用哪一个overrided函数。
: 2. 理解为什么从没有虚函数的基类到派生类的转型是危险的和dynamic_cast的使用场景。
: ...................