在面向对象的程序设计中,多态可以说是一块基石。在c++中这块基石主要是通过继承和虚函数来实现的,由于这两个机制(继承和虚函数)可能都是运行期进行处理的,因此我们把这种多态称为动态多态。模板中也存在多态机制,但是却不是动态多态,而是静态多态。模板中静态多态简单的理解就是在编译器进行处理,而不是运行期。在学习静态多态之前,先让我们回顾一下动态多态。
-
动态多态的设计思想:对于几个相关的对象模型,确定它们之间的一个共同功能集;然后在基类(父类)中,把这些共同的功能声明为多个虚函数的接口。然后让基类(父类)的虚函数接口指向派生类(子类)的对象。现在让我们简单的看看一个动多态的一个列子。
class Person {
public:
virtual void foot() {
std::cout << "People are footing";
}
};
class Jay :public Person {
void foot() override{
std::cout << "Jay sings while walking";
}
};
-
静多态不依赖与基类中包含公共行为的因素,每个对象模型是相互独立的,但仍然存在一种隐士的公共性。
class Person {
public:
void foot() {
std::cout << "People are footing" << std::endl;
}
};
class Jay {
public:
void foot() {
std::cout << "Jay sings while walking" << std::endl;
}
};
template<typename Person>
void foot1(Person& person) {
person.foot();
}
template<typename Person1>
void foot2(Person1& person1) {
person1.foot();
}
int main(void)
{
Person person;
Jay jay;
foot1<Person>(person);
foot2<Jay>(jay);
return 0;
}
现在让我们总结一下动态多态和静态多态的区别,从区别可以更好的理解模板的静态多态。
-
通过继承实现的多态是绑定和动态的。所以虚函数的执行在运行时期,是动态绑定的。
绑定:对于参与多态行为的类型,它们(具有多态行为)的接口是在公共基类的设计中就预先确定的,也就是说基类存在虚函数。
动态:接口的绑定是在运行期完成的。
-
通过模板实现的多态是非绑定和静态的。
非绑定:对于参与多态行为的类型,它们的接口预先是无法确定的,也就是说对象模型之间是相互独立的,所以不存在基类,但是却存在隐式的关联。
静态:接口的绑定是在编译器完成的。
-
那么二者优点和缺点时什么呢?