C++virtual 虚函数详解

首先看一下程序,猜猜运行结果是什么?

#include<iostream>
using namespace std;

class Animal
{
public:
Animal(int height,int weight)
{
cout<<"Animal construct"<<endl;
}
~Animal()
{
cout<<"Animal destruct"<<endl;
}

void eat()
{
cout<<"Animal's eat"<<endl;
}
protected:
void sleep() //在子类中可以访问 ,子类的sleep方法也是protected,不能被外部访问
{
cout<<"Animal's sleep"<<endl;
}

public:
void breathe() //c++多态性。
{

cout<<"Animal's breathe"<<endl;
}

};

class Fish :public Animal //按照public继承
{
public:

Fish():Animal(400,300) //在子类中向父类的构造函数传递参数,成功构造了animal对象
{
cout<<"fish construct"<<endl;
}
~Fish()
{
cout<<"fish destruct"<<endl;
}
void breathe()
{
Animal::breathe(); //::作用域标识符
cout<<"fish breath"<<endl;
}

};

void fn(Animal *pAn)
{
pAn->breathe();
}


void main()
{
//Animal an;
//an.eat();
Fish fh;
//fh.breathe();
//fh.test();
Animal *pAn;
pAn=&fh;
fn(pAn);
//两个对象的转换要内存模型匹配.pAn是animal和fish的首地址,

}

看main函数,首先声明了fish对象,再声明了一个animal 指针pAn,再把fh地址赋给pAn,最后调用fn函数,调用breath,到底

是哪个breath()?animal或者fish的?

 要回到这个问题,必须先看看fish的内存布局

C++virtual 虚函数详解

fish sh对象的地址还是同animal一样的,所以最后打印的是animal的breath()方法,如果想调用子类fish的breath()方法,怎么办?

只需这样改下:

virtual  void breathe() //c++多态性。会显示fish的breath方法

  虚函数,编译器编译时,发现breath是虚函数,会采用迟绑定,在运行时,依据对象的类型(在程序中,我们传递的Fish类对象的地址)来确认调用的哪一个函数,这种能力就做C++的多态性。

再接着改改,看看结果;

把fish的breath方法去掉,结果是什么?

是animal的breath(),

记住:父类virtual函数 ,(子类的地址)子类有的调用子类的,子类没有的调用父类的

原文链接: https://www.cnblogs.com/youxin/archive/2012/03/30/2425352.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++virtual 虚函数详解

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/45629

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 下午10:09
下一篇 2023年2月8日 下午10:10

相关推荐