多态浅析(C++)

来源:互联网 发布:强制删除用户 linux 编辑:程序博客网 时间:2024/05/20 23:36


       多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数实现的。

多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。

C++中,实现多态有以下方法:虚函数抽象类,覆盖,模板(重载和多态无关)。(本文主要以虚函数实现)

多态就是允许方法重名 参数或返回值可以是父类型传入或返回。


静态多态:编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则出现编译错误

#include<iostream>

using namespace std;

int Add(int num1,int num2)

{

return (num1+num2);

}

float Add(float  num1,float num2)

{

return (num1)

}

int main()

{

cout<<Add(10,20)<<endl;

cout<<Add(1.2,2.4)<<endl;

return 0;

}

动态多态

动态绑定:在程序执行期间(非编译期)判断所引用对象的实际类型,根据其实际类型调用相应的方法。使用virtual关键字修饰类的成员函数时,指明该函数为虚函数,派生类需要重新实现,编译器将实现动态绑定

【动态绑定条件】
1、必须是虚函数
2、通过基类类型的引用或者指针调用虚函数

举例:

#define _CRT_SECURE_NO_WARNINGS


#include <iostream>
#include <windows.h>
using namespace std;



class CWashRoom //厕所
{
public:
void GoToManWashRoom () //男人走左边
{
cout<< "Man--->Please Left" <<endl;
}
void GoToWomanWashRoom () //女人走右边
{
cout<< "Woman--->Please Right" <<endl ;
}
};
class CPerson
{
public:
virtual void GoToWashRoom(CWashRoom & _washRoom ) = 0;  

//在成员函数的形参后面写上=0,则成员函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。纯虚函数在派生//类中重新定义以后,派生类才能实例化出对象。
};
class CMan:public CPerson
{
public:
virtual void GoToWashRoom(CWashRoom & _washRoom )
{
_washRoom.GoToManWashRoom();
}
};
class CWoman:public CPerson
{
public:
virtual void GoToWashRoom(CWashRoom & _washRoom )
{
_washRoom.GoToWomanWashRoom ();
}
};
void FunTest()
{
CWashRoom washRoom;
for ( int iIdx = 1 ; iIdx <= 10 ; ++iIdx)
{
CPerson* pPerson;
int iPerson = rand ()%iIdx;
if (iPerson&0x01) //求余
{
pPerson = new CMan ; //创建一个新的对象,pPerson指向CMan
}
else
{
pPerson = new CWoman ;
}
pPerson->GoToWashRoom (washRoom);
delete pPerson;
pPerson = NULL ;
Sleep(1000 );
}
}


int main()
{
FunTest();
return 0;
}

总结:

1、派生类重写基类的虚函数实现多态,要求函数名、参数列表、返回值完全相同。(协变除外)
2、基类中定义了虚函数,在派生类中该函数始终保持虚函数的特性。
3、只有类的非静态成员函数才能定义为虚函数,静态成员函数不能定义为虚函数。
4、如果在类外定义虚函数,只能在声明函数时加virtual关键字,定义时不用加。
5、构造函数不能定义为虚函数,虽然可以将operator=定义为虚函数,但最好不要这么做,使用时容
易混淆
6、不要在构造函数和析构函数中调用虚函数,在构造函数和析构函数中,对象是不完整的,可能会
出现未定义的行为。
7、最好将基类的析构函数声明为虚函数。(析构函数比较特殊,因为派生类的析构函数跟基类的析构
函数名称不一样,但是构成覆盖,这里编译器做了特殊处理)
8、虚表是所有类对象实例共用的





0 0
原创粉丝点击