一个C++执行过程 关于虚拟函数

wenluderen 2013-12-23 03:51:18
代码如下:
#include <iostream.h>
//using namespace std;

class animal
{
public:
animal();//声明一个构造函数
~animal();//声明一个析构函数
void fun1(animal *maybedog_maybehorse);//定义了一个函数 形参是一个 animal类型的指针
virtual void born();//定义了一个虚函数 born
};

//以下内容是 类class里面的成员函数的定义
void animal::fun1(animal *maybedog_maybehorse)
{
maybedog_maybehorse->born();
}
animal::animal(){cout<<"执行类animal的构造函数"<<endl;}//一个空的构造函数
animal::~animal(){cout<<"执行类animal的析构函数"<<endl;}//一个空的析构函数
void animal::born()
{
cout<<"animal"<<endl;
cout<<"执行类animal的born函数"<<endl;
}
//以上完成了类animal的全部定义。
//以下定义了一个类horse ,该类从类animal继承下来。
class horse:public animal
{
public:
horse();//声明构造函数
~horse();//声明析构函数
virtual void born();//声明一个虚函数 born
};
horse::horse(){cout<<"执行类horse的构造函数"<<endl;} //类horse的构造函数定义
horse::~horse(){cout<<"执行类horse的析构函数"<<endl;}//类horse的析构函数的定义
void horse::born()
{
cout<<"horse"<<endl;
cout<<"执行类horse的born函数"<<endl;
}
//以上完成了类horse的全部定义
//以下正式进入主函数 main

int main()
{
cout<<"进入main函数"<<endl;
animal a;//定义类animal的一个实例对象 a;
cout<<"完成a定义"<<endl;
horse b;//定义类horse的一个实例对象 b;
cout<<"完成b定义"<<endl;
a.fun1(&b);//将对象b的地址传递给函数对象a的fun1函数
cout<<"主函数完成调用对象a的是fun1函数"<<endl;
cout<<"******************"<<endl;
return 0;
}





主函数中调用了a.fun1(&b);将对象b的地址传递给函数对象a的fun1函数,

然后开始执行函数a.fun1(animal *maybedog_maybehorse),此处fun1的形参是一个animal类型的指针。

用这个指针存储对象b的地址。

问题一:a.fun1函数内容是maybedog_maybehorse->born(); 是不是代用了对象b的born函数??????

问题二:类animal 和类horse中都有成员函数born,类horse公开继承了类animal。那么这两个born函数有什么关系吗。

问题三:两个类(animal和 horse)中的born 都是 虚函数。此处虚函数起到一个什么作用呢?

无知小白问了一个简答问题,还望各位大牛给点帮助。

谢谢
...全文
171 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
wenluderen 2014-01-01
  • 打赏
  • 举报
回复
今天终于差不多明白了 虚函数 ,原来这货是和类的多态纠缠在一起的。 谢谢 楼上各位。
vipcxj 2013-12-23
  • 打赏
  • 举报
回复
问一:你都已经运行过了,控制台上已经说的非常清楚了,到底调用了谁的born函数,所以这个问题实在很没水平。 问二/问三:你应该去百度下什么是虚函数。我这里就先简单说明下。 首先虚函数值对指针和引用有效,你的例子中用的就是指针。

void animal::fun1(animal *maybedog_maybehorse)
{
    maybedog_maybehorse->born(); //这里的maybedog_maybehorse是基类animal的指针。但具体调用基类animal的born还是子类horse的born主要看maybedog_maybehorse是用什么构造的。本例中你实际传入的参数是horse的指针,所以它调用的就是horse的born。要出现以上特性,就必须在基类的同名函数上加上virtual关键字。子类的同名函数born其实加不加这个关键字都可以。
}
再举个具体的例子

struct Base
{
   virtual void foo() const {};
}

struct Derive : Base
{
   void foo() const {};
}

int main()
{
   Base * B = new Base;
   Base * D = new Derive;
   B -> foo(); //这个调用的就是Base的foo
   D -> foo(); //这个调用的就是Derive的foo,虽然它和B同样都是指向Base的指针。
   return 0;
}
derekrose 2013-12-23
  • 打赏
  • 举报
回复
问题一:调试就知道了啊 问题二:同名函数,功能性肯定是有相似的地方,但是这里是override的一个例子 问题三:去看看虚函数那一章
wenluderen 2013-12-23
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
多谢 虽然我用的简版的VC但是也能用你所说的功能 ,虽然我不定汇编。
wenluderen 2013-12-23
  • 打赏
  • 举报
回复
引用 2 楼 billzheng 的回复:
There is no iostream.h in C++ standard, should be:

#include <iostream>
using namespace std;
谢谢
赵4老师 2013-12-23
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
billzheng 2013-12-23
  • 打赏
  • 举报
回复
There is no iostream.h in C++ standard, should be:

#include <iostream>
using namespace std;
wenluderen 2013-12-23
  • 打赏
  • 举报
回复
忘记说了 IDE是VC++ 6.0.

没有使用using namespace std;似乎也不可以使用。

不然报错。

64,643

社区成员

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

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