1 概述
多态,意思既是同一个事物的多种形态,用C++的专业词语来说就是:一个接口、多种实现方式。
2 多态
2.1 分类
- 静态多态
- 函数重载
- 泛型编程
- 动态多态
- 虚函数
2.2 静态多态
静态多态是编译时的多态。
2.2.1 函数重载
函数重载是函数名称相同,参数类型或个数不同:
int Add(int a, int b) { return a + b; }
float Add(float a, float b) { return a + b; }
函数Add的功能统一,只是数据类型不同。
2.2.2 泛型编程
C++泛型编程就是模板编程,如下:
template<class T>
T AddT(T a, T b)
{
return a + b;
}
函数模板AddT提供两个函数数相加,参数类型不同,但参数个数相同。
2.2.3 实例
#include <iostream>
int Add(int a, int b) { return a + b; }
float Add(float a, float b) { return a + b; }
template<class T>
T AddT(T a, T b)
{
return a + b;
}
int main(int argc, char *argv[])
{
int intA = 1;
int intB = 2;
float floatA = 1.0;
float floatB = 4.0;
std::cout << Add(intA, intB) << std::endl;
std::cout << Add(floatA, floatB) << std::endl;
std::cout << AddT(intA, intB) << std::endl;
std::cout << AddT(floatA, floatB) << std::endl;
return 0;
}
运行结果:
3
5
3
5
2.3 动态多态
动态多态是运行时的多态。C++通过虚函数实现多态,就是在成员函数前面加virtual修饰。
2.3.1 实例
class Base
{
public:
virtual ~Base()
{
std::cout << "~Base()" << std::endl;
}
virtual void doSomeThing() = 0;
virtual void saySomeWords() {}
};
class Class1 : public Base
{
public:
~Class1()
{
std::cout << "~Class1" << std::endl;
}
void doSomeThing() override
{
std::cout << "Class1:doSomeThing()" << std::endl;
}
};
class Class2 : public Base
{
public:
~Class2()
{
std::cout << "~Class2" << std::endl;
}
void doSomeThing() override
{
std::cout << "Class2:doSomeThing()" << std::endl;
}
};
int main(int argc, char *argv[])
{
std::vector<Base *> classVector;
classVector.push_back(new Class1());
classVector.push_back(new Class2());
for(std::vector<Base *>::iterator it = classVector.begin(); it != classVector.end(); ++it)
(*it)->doSomeThing();
for(std::vector<Base *>::iterator it = classVector.begin(); it != classVector.end(); ++it)
delete (*it);
std::list<Base *> classList;
classList.push_back(new Class1());
classList.push_back(new Class2());
for(std::list<Base *>::iterator it = classList.begin(); it != classList.end(); ++it)
(*it)->doSomeThing();
for(std::list<Base *>::iterator it = classList.begin(); it != classList.end(); ++it)
delete (*it);
typedef std::shared_ptr<Base> BasePtr;
std::vector<BasePtr> bases;
bases.push_back(std::make_shared<Class1>());
bases.push_back(std::make_shared<Class2>());
for(auto it = bases.begin(); it != bases.end(); ++it)
(*it)->doSomeThing();
return 0;
}
注意:
- Base的析构函数定义为虚函数是为通过Base释放对象时保证派生类的析构函数可以被调用。
- Base的doSomeThing函数被定义为纯虚函数,派生类必须重载该函数。含有纯虚函数的类称为纯虚类,不能被实例化对象。
- Base的saySomeWords是一个非纯虚函数,派生类可以重载也可以不重载。
- 派生类重载函数需要在函数名称后面加关键字override.
2.3.2 运行结果
Class1:doSomeThing()
Class2:doSomeThing()
~Class1
~Base()
~Class2
~Base()
Class1:doSomeThing()
Class2:doSomeThing()
~Class1
~Base()
~Class2
~Base()
Class1:doSomeThing()
Class2:doSomeThing()
~Class1
~Base()
~Class1
~Base()
3 总结
- 静态多态: 重载函数和模板机制使我们编程时简化了命名和算法实现类型无关化,使代码更优雅。
- 动态多态: 虚函数机制使我们管理相似对象更优雅,代码更简化。是面向对象编程的基础。