继承 虚函数

yixiayizi 2010-11-07 08:19:39

#include<iostream>
using namespace std;

class A
{
public:
void virtual f()
{ cout << "A" << endl; }
};

class B:public A
{
public:
void f()
{ cout << "B" << endl; }
};

int main()
{
A * pa = new A();
pa->f();
B * pb = (B*) pa;//求解释这个会得到什么输出
pb->f();

delete pa, pb;
pa = new B();
pa->f();
pb = (B*) pa;//求解释这个会得到什么输出
pb->f();

return 0;
}


这种强制转换会有哪些改变发生呢?

谢谢指点
...全文
163 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
失落的凡凡 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jhangverita 的回复:]

子类转换成父类平滑。父类转换成子类就不可以,就像double转换成int。
[/Quote]

今天见你几次了,每次看到你的回答总是让我忧郁。
xili 2010-11-08
  • 打赏
  • 举报
回复
头疼,危险操作,结果不可预料
hukui161 2010-11-08
  • 打赏
  • 举报
回复
不解释++
zshtiger2414 2010-11-08
  • 打赏
  • 举报
回复
指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。
zshtiger2414 2010-11-08
  • 打赏
  • 举报
回复
http://baike.baidu.com/view/161302.htm
zshtiger2414 2010-11-08
  • 打赏
  • 举报
回复
我试验了下,输出是

A
A
B
B

是不是具体开辟的空间是什么类型的就调用谁的虚函数啊?
k_sh_y 2010-11-08
  • 打赏
  • 举报
回复
A * pa = new A();
pa->f();
B * pb = (B*) pa;//求解释这个会得到什么输出
pb->f();
A的虚函数表中只有一个虚函数,f()
B的虚函数表中也只有一个虚函数,f()
将A的对象的指针强转成B的,但指向的内存中放的还是A的对象信息,
当你调用pb->f()时,f()是个虚函数,就去虚函数表中查找,找的时侯是按虚函数在表中的下标找的.
找到调用f(),而内存中是A对象的信息,所以调用了A中f()的实现

pa = new B();
pa->f();
pb = (B*) pa;//求解释这个会得到什么输出
pb->f();
这个内存中是B类对象的信息,应该调用B中f()的实现
jikeyuan1 2010-11-08
  • 打赏
  • 举报
回复
继续等待。。。。
mumuliang 2010-11-08
  • 打赏
  • 举报
回复
A * pa = new A();
pa->f();
B * pb = (B*) pa;//求解释这个会得到什么输出
pb->f();

delete pa, pb;
pa = new B();
pa->f();
pb = (B*) pa;//求解释这个会得到什么输出
pb->f();
-------------------------
A
A
B
B
---------------
13没什么说的吧,4的话,看起来有许多未知的样子。
2的话,应该是这样理解吧。

普通成员函数被调用是直接跳转到函数,虚函数是先从类中的一个指针(编译器会帮你做这件事)找到一个虚函数地址列表,然后再按图索骥找到函数。


A对象pa被强制转换为B,也就是把pa的数据空间按照B的规则来重新管理,只是重新管理,数据不会变化。

f()是一个虚函数,在pa的数据空间里,是找不到它的(其他普通成员函数都能在此找到)。这里放的不是f(),而是一个指针,这个指针指向的是一个函数地址列表,在这个地址列表中才存放了f()的地址。

pa是对象A的时候,这个指针指向A的地址列表,pa被强制转换成B,这个指针此时的“含义”会变成B类中指向虚函数的地址列表的指针,但它的数据(所指的函数地址列表)并没有发生变化,因此作为B的pa,也就是(B*)pa,它f()时,调用的仍然是A类的虚拟函数地址列表中的f(),让然会输出A。
失落的凡凡 2010-11-08
  • 打赏
  • 举报
回复
1楼2楼不解释是有道理的。虚函数这个概念在C++中非常重要,入门时至少应该了解它的行为。让你困惑的往往不是它的行为是如何如何,而是为什么要有这个行为,不用急,慢慢你就体会到了。
jhangverita 2010-11-07
  • 打赏
  • 举报
回复
子类转换成父类平滑。父类转换成子类就不可以,就像double转换成int。

黑娃 2010-11-07
  • 打赏
  • 举报
回复
B * pb = (B*) pa;//pa原来指向什么现在还是指向什么,只不过现在pa的类型从A*变成了B*。pb也指向了pa所指的对象
jikeyuan1 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 falcomavin 的回复:]

f是virtual,所以会在运行时确定指针指向A还是B
B * pb = (B*) pa;//强制让pb指向pa所指,就是让pa也成为B*类型了,但pa原来所指的并不会改变
[/Quote]

有点道理 不过还是有点不明白啊 等待.......
黑娃 2010-11-07
  • 打赏
  • 举报
回复
f是virtual,所以会在运行时确定指针指向A还是B
B * pb = (B*) pa;//强制让pb指向pa所指,就是让pa也成为B*类型了,但pa原来所指的并不会改变
cumt_TTR 2010-11-07
  • 打赏
  • 举报
回复
A * pa = new A() ??

void virtual f()
是不是 virtual void f()??
knowcraft 2010-11-07
  • 打赏
  • 举报
回复
object slicing
liutengfeigo 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 qq120848369 的回复:]

不解释.
[/Quote]
++

64,646

社区成员

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

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