别的不说,直接上代码。
class Animal
{
public:
Animal(int height,int weight);
void breathe();
};
class Fish : public Animal
{
public:
Fish();
void breathe();
}
void fn(Animal *pAn)
{
pAn->breathe();
}
void main()
{
Fish fh;
Animal *pAn;
pAn=&fh;
fn(pAn);
}
这里主函数中,pAn=&fh将Fish的指针赋值给Animal指针pAn,这种子类想父类赋值的方式成为向上传递,由于两个的类存模型为下图
由于两者的内存模型匹配,当Fish的指针赋值给Animal指针时,fn转化为了pAn,所以在函数fn(pAn)中,pAn->breathe()运行了Animal::breathe()。
但是,再看下面的代码:
class Animal
{
public:
Animal(int height,int weight);
virtual void breathe();
};
class Fish : public Animal
{
public:
Fish();
void breathe();
}
void fn(Animal *pAn)
{
pAn->breathe();
}
void main()
{
Fish fh;
Animal *pAn;
pAn=&fh;
fn(pAn);
}
一个virtual导致完全不同的结果,这正是C++多态的作用。直接上概念,分析。
n 多态性
当C++编译器在编译的时候,发现Animal类的breathe()函数是虚函数,这个时候C++就会采用迟绑定(late binding)的技术,在运行时,依据对象的类型(在程序中,我们传递的Fish类对象的地址)来确认调用的哪一个函数,这种能力就做C++的多态性。
所以,在pAn=&fh;他在上面的第一个代码中在编译阶段就确定pAn为Animal指针,所以在函数fn(pAn)中运行Animal::breathe()。而第二段代码中,由于父类Animal中virtual void breathe()声明为了虚函数,pAn=&fh在运行阶段,将fn赋值给了pAn,而fn本身是
fish类型指针,所以,pAn->breathe()运行了fish::breathe()。