#include "stdafx.h"
#include <iostream>
using namespace std;
class animal
{
public:
void eat(){ cout << "animal eat" << endl; }
void sleep(){ cout << "animal sleep" << endl; }
void breathe(){ cout << "animal breathe" << endl; }
};
class fish :public animal
{
public:
void breathe(){ cout << "fish bubble" << endl; }
};
void fn(animal *pAn)
{
pAn->breathe();
}
int _tmain(int argc, _TCHAR* argv[])
{
animal *pAn;
fish fh;
pAn = &fh;
fn(pAn);
return 0;
}
输出结果:</span><pre name="code" class="cpp"><span style="font-size:18px;">animal breathe</span>
分析:因为在fish类的对象fh的地址赋给pAn时,C++编译器进行了类型转换,此时C++编译器认为变量pAn保存就是Animal
对象的地址。当在fn函数中执行pAn->breathe()时,调用的当然就是animal对象的breathe的函数。
下图为fish对象内存模型:
当我们构造fish类的对象时,首先要调用animal类的构造函数去构造animal类的对象,然后才调用fish类的构造函数完成
自身部分的构造,从而拼接出一个完整的fish对象。当我们将fish类的对象转换为animal类型时,该对象就被认为是原对
象整个内存模型的上半部分。即“animal的对象所占内存”。当我们利用类型转换后的对象指针去调用它的方法时,自然
也就是调用它所在的内存中的方法。
现在我们在animal类的breathe()方法上加上virtual关键字。
#include "stdafx.h"
#include <iostream>
using namespace std;
class animal
{
public:
void eat(){ cout << "animal eat" << endl; }
void sleep(){ cout << "animal sleep" << endl; }
virtual void breathe(){ cout << "animal breathe" << endl; }//添加virtual关键字,成为此函数为虚函数
};
class fish :public animal
{
public:
void breathe(){ cout << "fish bubble" << endl; }
};
void fn(animal *pAn)
{
pAn->breathe();
}
int _tmain(int argc, _TCHAR* argv[])
{
animal *pAn;
fish fh;
pAn = &fh;
fn(pAn);
return 0;
}
输出结果:
fish bubble
分析:这就是C++的多态性。在C++编译器在编译的时候,发现animal类的breathe()函数是虚函数,此时C++就会采用
迟绑定技术。也就是编译时并不确定具体调用的函数,而是在运行时,根据对象的类型类确认调用是哪一个函数,这种
能力就叫做C++的多态性。
C++的多态性的概括:在基类的函数上加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型
来调用相应的函数。