首先看一下程序,猜猜运行结果是什么?
#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的内存布局
fish sh对象的地址还是同animal一样的,所以最后打印的是animal的breath()方法,如果想调用子类fish的breath()方法,怎么办?
只需这样改下:
virtual void breathe() //c++多态性。会显示fish的breath方法
虚函数,编译器编译时,发现breath是虚函数,会采用迟绑定,在运行时,依据对象的类型(在程序中,我们传递的Fish类对象的地址)来确认调用的哪一个函数,这种能力就做C++的多态性。
再接着改改,看看结果;
把fish的breath方法去掉,结果是什么?
是animal的breath(),
记住:父类virtual函数 ,(子类的地址)子类有的调用子类的,子类没有的调用父类的。