当前位置:   article > 正文

C++ 动多态 vs 静多态_动态多态的优点

动态多态的优点

 


《c++ templates, chapter14》


Summary

术 语:

---通过继承实现的多态是 绑定的  和  动态的。

绑定指: 各个子类的接口需要与公共基类的虚函数相同。 有时,也把绑定这个概念称为入侵的或插入的。

动态指: 接口的绑定是在运行期完成的。用基类的指针去调用哪个子类的虚函数呢,运行时才确定;

 

---通过模板实现的多态是 非绑定的 和 静态的

非绑定指: 不需要基类提供公共的接口。

静态指: 接口的绑定是在编译期完成的,即在编译器确定调用的哪个类的哪个具体的函数。
 

在其他语言中,还可能会有其他组合存在,例如smalltalk提供了非绑定的动态多态。

 

-----优点和缺点:

c++动态多态的优点:

# 能够优雅地处理异类集合;

# 可执行代码通常比较小(因为对于静多态而言,为处理不同的类型必须生成多个不同的模板实例。例如,下面的myDraw(const GeoObj& obj)函数,对于动态多态而言,

  只需要一份函数,但是对于静态多态而言,需要根据调用情况,生成myDraw_t<Line_t>, myDraw_t<Circle_t>等多份函数。)

 

c++静态多态的优点:

@ 代码效率较高,因为相比动态多态,其不存在通过指针的间接引用;

@ 具有更好的类型安全性,因为静多态会对所有的绑定操作进行检查。

缺陷:使用静多态后,再也不能透明地处理异类的集合;所有的类型都必须在编译期间确定;


动多态

基类的指针指向子类对象,实现虚函数的动态绑定。

对于动态多态,相当引人注目的一个特点是处理异类容器的能力! 如下的drawElems函数。

  1. //base calss
  2. class GeoObj {
  3. public:
  4. virtual void draw() const = 0;
  5. virtual float centerX_of_gravity() const = 0;
  6. };
  7. class Circle :public GeoObj {
  8. public:
  9. virtual void draw() const override
  10. {
  11. cout << "draw Circle\n";
  12. }
  13. virtual float centerX_of_gravity() const override {
  14. cout << "Called Circle::centerX_of_gravity" << endl;
  15. return 0.f;
  16. }
  17. };
  18. class Line :public GeoObj {
  19. public:
  20. virtual void draw() const override
  21. {
  22. cout << "draw Line\n";
  23. }
  24. virtual float centerX_of_gravity() const override {
  25. cout << "Called Line::centerX_of_gravity" << endl;
  26. return 0.f;
  27. }
  28. };

客户端代码:

  1. void myDraw(const GeoObj& obj) {
  2. obj.draw();
  3. }
  4. float distanceOfX(const GeoObj& obj1, const GeoObj& obj2) {
  5. float disX = obj1.centerX_of_gravity() - obj2.centerX_of_gravity();
  6. return std::fabs(disX);
  7. }
  8. //处理异类集合
  9. void drawElems(const vector<GeoObj*>& elems) {
  10. for (const auto& it: elems) {
  11. it->draw();
  12. }
  13. }
  14. int main() {
  15. Line line;
  16. Circle c, c1, c2;
  17. myDraw(line);
  18. myDraw(c);
  19. distanceOfX(line, c1);
  20. vector<GeoObj*> elemsVec;
  21. elemsVec.push_back(&line);
  22. elemsVec.push_back(&c1);
  23. elemsVec.push_back(&c2);
  24. drawElems(elemsVec);
  25. return 0;
  26. }

 


静多态

模板也能用于实现多态,这种多态不依赖于基类的存在 (动态多态需要在基类中声明公共的函数接口)。

这种多态的“公共性”体现在各个不同的类都需要支持某些公共的函数接口。另外,各个类之间是相互独立的哦

  1. //具体的几何类。没有派生自其它任何类
  2. class Circle_t {
  3. public:
  4. void draw() const
  5. {
  6. cout << "draw Circle\n";
  7. }
  8. float centerX_of_gravity() const {
  9. cout << "Called Circle_t::centerX_of_gravity" << endl;
  10. return 0.f;
  11. }
  12. };
  13. class Line_t {
  14. public:
  15. void draw() const
  16. {
  17. cout << "draw Line\n";
  18. }
  19. float centerX_of_gravity() const {
  20. cout << "Called Line_t::centerX_of_gravity" << endl;
  21. return 0.f;
  22. }
  23. };
  24. class Check_t {
  25. public:
  26. void drawError() const
  27. {
  28. cout << "draw Line\n";
  29. }
  30. };

客户端的使用:

  1. template <class T>
  2. void myDraw_t(const T& obj) {
  3. obj.draw();
  4. }
  5. template <class T1, typename T2>
  6. float distanceOfX_t(const T1& obj1, const T2& obj2) {
  7. float disX = obj1.centerX_of_gravity() - obj2.centerX_of_gravity();
  8. return std::fabs(disX);
  9. }
  10. //只能将同类对象放到一个容器中:
  11. template<class T>
  12. void drawElems_t(const vector<T*>& elems) {
  13. for (const auto& it : elems) {
  14. it->draw();
  15. }
  16. }
  17. int main() {
  18. Line_t line;
  19. Line_t line1;
  20. myDraw_t(line); //编译器检测到该行后,会生成一个函数实例myDraw_t<Line_t>
  21. Circle_t c1;
  22. Circle_t c2;
  23. myDraw_t(c1); //编译器检测到该行后,会生成一个函数实例myDraw_t<Circle_t>
  24. distanceOfX_t(line,c1);//编译器检测到该行后,会生成一个函数实例distanceOfX_t<Line_t, Circle_t>
  25. vector<Line_t*> vect;
  26. vect.push_back(&line);
  27. vect.push_back(&line1);
  28. //vect.push_back(&c1); 不能酱Circle_t的对象放进去哦
  29. drawElems_t(vect);
  30. //Check_t checkObj;
  31. //myDraw_t(checkObj);//编译期间就可以检查出draw函数不是Check_t类的成员函数。
  32. return 0;
  33. }

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/427668
推荐阅读
相关标签
  

闽ICP备14008679号