“多态”是同一名字的事物可以完成不同的功能。多态可以分为编译时的多态和运行时的多态。前者主要是指函数的重载(包括运算符的重载),对重载函数的调用,在编译时就能根据实参确定应该调用哪个函数;而后者则和继承、虚函数等概念有关;
派生类的指针可以赋值给基类指针。对于通过基类指针,调用基类和派生类都有的同名、同参数表的虚函数这样的语句,编译时并不确定执行的是基类还是派生类的虚函数;而当程序运行到该条语句时,如果该基类指针指向的是一个基类对象,则调用基类的虚函数,如果该基类指针指向的是一个派生类对象,则调用派生类的虚函数。这种机制就称为“多态”。
下面的例子可以体现多态规则。
//============================================================================
// Name : duotai.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
class A
{
public:
virtual void Func()
{
cout<<"A:Func"<<endl;
}
};
class B:public A
{
public:
virtual void Func()
{
cout<<"B:Func"<<endl;
}
};
class C:public A
{
public:
virtual void Func()
{
cout<<"C:Func"<<endl;
}
};
int main() {
A *p=new A();
A *q=new B();
A *t=new C();
p->Func();
q->Func();
t->Func();
return 0;
}
结果如下:
A:Func
B:Func
C:Func
为什么要使用虚函数:
一、可以同一个指令使得不同派生类对象执行各自的行为,提高效率;
二、如果一个基类派生了若干个派生类,然后某个函数的返回值是其中一个派生类,但是是通过case返回不同的派生类,在后续需要这个函数的返回值时,不用为了调用派生类里的某个函数而去判断派生类,可以直接将返回值的类型定义为基类,例子如下:
#include<iostream>
using namespace std;
class Father
{
public:
virtual void printinfo()
{
cout<<"father"<<endl;
}
};
class Son:public Father
{
public:
virtual void printinfo()
{
cout<<"son"<<endl;
}
};
class Func
{
public:
void Setname(Father* test)
{
m_test=test;
}
Father* Getname()
{
return m_test;
}
private:
Father* m_test;
};
void Test(int i)
{
Father *Name;
Func *func=new Func();
switch(i)
{
case 1:
Name=new Father();
func->Setname(Name);
func->Getname()->printinfo();
break;
case 2:
Name=new Son();
func->Setname(Name);
func->Getname()->printinfo();
break;
default:
break;
}
}
int main()
{
Test(1);
Test(2);
return 0;
}
使用了虚函数的话,Getname的返回值就可以直接定义为父类,在使用的使用的时候再根据具体参数来设置类,提高了效率。
emmmmmm,举的例子有点累赘了,但很多需要set、get函数封装维护的时候多态的作用就很明显了。