C++编程学习总结1

编程笔记 | 虚函数与多态

Posted by 陈陈 on December 3, 2020

因项目需要,开始采用C++编程。尽管C++可以看作是C语言的一个继承和发展,但众多新的特性,例如继承和多态,又使得其完全不同于C。C++要求编程人员更加注重程序的架构和设计,必须要有全局的眼光和思路,非常适合大型程序的开发和管理,值得深入学习。

本系列为C++编程学习的相关总结。


通常,程序中不能定义两个名字相同、参数个数和类型都相同的函数的,这将会报“重复定义” 的错误,因为程序不知道该调用哪一个。

但有的情况下,我们需要同一个函数做不同的事情。例如,对于一个求面积的函数,若对象是圆,面积是圆周率乘以半径的平方;若对象是长方形,则应该是长乘以宽。如何做到这一点?

C++ 中引入了虚函数的概念,它的作用就是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。这样就可以实现上述功能,我们称之为多态(polymorphism)

要实现多态,还需要在程序中进行动态绑定。C++中的函数默认不使用动态绑定,要触发动态绑定,必须满足两个条件:

  1. 只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不进行动态绑定;
  2. 必须通过基类类型的指针或引用进行函数的调用。

虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。

用下面代码演示多态和非多态。


  #include<iostream>
  using namespace std;
  class A
  {
  public:
      void foo()
      {
          printf("1\n");
      }
      virtual void fun()
      {
          printf("2\n");
      }
  };
  class B : public A
  {
  public:
      void foo()  //隐藏:派生类的函数屏蔽了与其同名的基类函数
      {
          printf("3\n");
      }
      void fun()  //多态、覆盖
      {
          printf("4\n");
      }
  };
  int main(void)
  {
      A a;
      B b;
      A *p = &a; //动态绑定
      p->foo();  //输出1
      p->fun();  //输出2
      p = &b;
      p->foo();  //取决于指针类型,输出1
      p->fun();  //取决于对象类型,输出4,体现了多态
      return 0;
  } > -------------------------

由上述例子可知,同样是函数fun,却实现不同功能。这是通过首先将“fun”定义为虚函数,然后在B类中将其覆盖,最后通过p指针的动态绑定实现了多态