我不认识她!

lsrj 2005-04-28 07:32:50
请看下面的程序
#include<iostream>
using namespace std;
class A{ //虚函数示例代码2
public:
virtual void fun(){ cout<<"A::fun"<<endl;}
virtual void fun2(){cout<<"A::fun2"<<endl;}
};
class B:public A{
public:
void fun(){ cout<<"B::fun"<<endl;}
void fun2(){ cout<<"B::fun2"<<endl;}
};
int main(){
void (A::*fun)();
A *p=new B;//p是初始化为B的地址吧?
fun=&A::fun;//这一句fun是存的A的地址吗?
(p->*fun)();//这一句就比较绕,看不懂了!
fun = &A::fun2;
(p->*fun)();
delete p;
system("pause");
}
恳请老手们给个答案。
...全文
159 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
MagicCarmack 2005-04-29
  • 打赏
  • 举报
回复
学习
pzh508 2005-04-28
  • 打赏
  • 举报
回复
一句话:无论你new了父类指针还是子类指针,当调用虚函数时,只要子类改写了该虚函数,那么就调用子类的实现部分,如果子类没有改写虚函数的内容,则相应调用父类的实现部分 (这里的代码只是使用函数指针而已)
zhangsong1238 2005-04-28
  • 打赏
  • 举报
回复
我是新手,在纸上画了一半天,才弄明白楼主的意思,int main(){
void (A::*fun)();
A *p=new B;//p是初始化为B的地址吧?//这是很多教科书上用来证明虚函数的作用的写法,这样P就实现了动态绑定。
fun=&A::fun;//这一句fun是存的A的地址吗?//就是存fun的地址
(p->*fun)();//这一句就比较绕,看不懂了!//这一句就是调用函数了,P是一个指向B类对象的一个指针,*fun是一个指向函数的指针,如果能画图就很清晰的表示的,下面的步骤也是一样的
fun = &A::fun2;
(p->*fun)();
delete p;
system("pause");
}
结果为B::fun
A::fun2
qrlvls 2005-04-28
  • 打赏
  • 举报
回复
其实这个程序想要告诉你的是:
虚函数的实现是将虚函数地址当作类似成员变量的方法来存储的,这就是虚函数表
参考上面说的第1条
a.fun本来应该输出A::fun,而p是A类型指针却输出了B::fun
这说明一点:A::fun 和 B::fun 的函数指针是位于同一个地址
qrlvls 2005-04-28
  • 打赏
  • 举报
回复
上面有三个知识点
1.类与父类编译后对象的空间地址分配
每个对象独立占用地址空间的部分包括虚函数表和成员变量,而成员函数不是这样
2.函数指针类型
3.在调用类函数的情况下,编译器实际上是将对象的地址作为一个this指针传递给成员函数
比如C++中一个对象 x 可以有两个成员函数 val(); 和 add(v1, v2);
你在纯C中可以使用 val(struct s*) 和 add (struct s*, v1, v2) 的方法来实现这种面向对象的思想,而事实上编译器也是这么做的
qrlvls 2005-04-28
  • 打赏
  • 举报
回复
其实这样写更容易明白

typedef void (A::*FuncPtr)();

void main()
{
FuncPtr pFunc; // pFunc 是一个 A 的成员函数指针类型,类型与 A::fun 的指针相同
A *p;

p = (A*) new B;
(p->*pFunc)(); // B是A的子类,因此这种转换是合法的,因为A对象的内存空间排列与B的前一部分是相同的
pFunc = &A::fun; // pFunc 指针指向 A::fun 函数
(p->*pFunc)(); // pFunc 是函数指针,因此 *pFunc 才表示函数
// 而 *pFunc 的类型是成员函数,因此不能用 (*pFunc)() 调用
// 成员函数调用时 a.fun() 其实代表 fun(&a),而 &a 就是 this 指针
// 因此这里 (p->*pFunc)() 代表 (*pFunc)(p);
// 可以这样理解,但 (*pFunc)(p) 的写法是不合格的
// 但这就是 C++ 编译器的思维方式

pFunc = &A::fun2;
(p->*pFunc)(); // 这两句与上两句相同用法

delete p;

system("pause");
}
bianliuwei 2005-04-28
  • 打赏
  • 举报
回复
楼主需要看些基础的c++书,最好国外的
useresu 2005-04-28
  • 打赏
  • 举报
回复
因为父类的函数fun和fun2是virtual的,
所以虽然指针p是A类型的,但是却指向B类型,
由于virtual函数是动态绑定的,
所以调用的是B的成员函数.

这就是多态啊.
useresu 2005-04-28
  • 打赏
  • 举报
回复
(p->*fun)();//这句是用指针p调用A的成员函数fun()
useresu 2005-04-28
  • 打赏
  • 举报
回复
A *p=new B;//用父类指针指向一个子类的对象,
void (A::*fun)(); 是个函数指针,
指向A的成员函数 fun(),即下一句
fun=&A::fun;//
lsrj 2005-04-28
  • 打赏
  • 举报
回复
不明白这个结果
lsrj 2005-04-28
  • 打赏
  • 举报
回复
输出的结果是
B::fun
B::fun2
bianliuwei 2005-04-28
  • 打赏
  • 举报
回复
一、new在动态内存区域申请了一块空间,返回的是那块空间的首地址,由p指向
二、是放的fun的地址,类似于函数指针的作用
三、其实就是使用函数指针调用函数

64,654

社区成员

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

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