C++编译期多态与运行期多态
来源:https://www.cnblogs.com/QG-whz/p/5132745.html
前言
什么是运行期多态 什么是编译期多态 它们的优缺点在哪
运行期多态
class Animal
{
public :
virtual void shout() = 0;
};
class Dog :public Animal
{
public:
virtual void shout(){ cout << "汪汪!"<<endl; }
};
class Cat :public Animal
{
public:
virtual void shout(){ cout << "喵喵~"<<endl; }
};
class Bird : public Animal
{
public:
virtual void shout(){ cout << "叽喳!"<<endl; }
};
int main()
{
Animal * anim1 = new Dog;
Animal * anim2 = new Cat;
Animal * anim3 = new Bird;
//藉由指针(或引用)调用的接口,在运行期确定指针(或引用)所指对象的真正类型,调用该类型对应的接口
anim1->shout();
anim2->shout();
anim3->shout();
//delete 对象
...
return 0;
}
//我们有个动物园,里面有一堆动物
int main()
{
vector<Animal*>anims;
Animal * anim1 = new Dog;
Animal * anim2 = new Cat;
Animal * anim3 = new Bird;
Animal * anim4 = new Dog;
Animal * anim5 = new Cat;
Animal * anim6 = new Bird;
//处理异质类集合
anims.push_back(anim1);
anims.push_back(anim2);
anims.push_back(anim3);
anims.push_back(anim4);
anims.push_back(anim5);
anims.push_back(anim6);
for (auto & i : anims)
{
i->shout();
}
//delete对象
//...
return 0;
}
编译期多态
相比较于运行期多态,实现编译期多态的类之间并不需要成为一个继承体系,它们之间可以没有什么关系,但约束是它们都有相同的隐式接口。我们将上面的例子改写为:
class Animal
{
public :
void shout() { cout << "发出动物的叫声" << endl; };
};
class Dog
{
public:
void shout(){ cout << "汪汪!"<<endl; }
};
class Cat
{
public:
void shout(){ cout << "喵喵~"<<endl; }
};
class Bird
{
public:
void shout(){ cout << "叽喳!"<<endl; }
};
template <typename T>
void animalShout(T & t)
{
t.shout();
}
int main()
{
Animal anim;
Dog dog;
Cat cat;
Bird bird;
animalShout(anim);
animalShout(dog);
animalShout(cat);
animalShout(bird);
getchar();
}
运行期多态与编译期多态优缺点分析
运行期多态优点
OO设计中重要的特性,对客观世界直觉认识。 能够处理同一个继承体系下的异质类集合。
运行期多态缺点
运行期间进行虚函数绑定,提高了程序运行开销。 庞大的类继承层次,对接口的修改易影响类继承层次。 由于虚函数在运行期在确定,所以编译器无法对虚函数进行优化。
编译期多态优点
它带来了泛型编程的概念,使得C++拥有泛型编程与STL这样的强大武器。 在编译器完成多态,提高运行期效率。 具有很强的适配性与松耦合性,对于特殊类型可由模板偏特化、全特化来处理。
编译期多态缺点
程序可读性降低,代码调试带来困难。 无法实现模板的分离编译,当工程很大时,编译时间不可小觑。 无法处理异质对象集合。
关于显式接口与隐式接口
void AnimalShot(Animal & anim)
{
anim.shout();
}
template <typename T>
void AnimalShot(T & anim)
{
anim.shout();
}
评论