虚函数的继承与重写

  • 在定义派生类时,可以决定继承基类的虚函数还是覆盖,若是继承纯虚函数,该派生类也会变成抽象类;
  • 覆盖虚函数必须有完全相同的函数原型;
    • 参数列表
    • 返回类型
    • 常量性 :::info 派生类中virtual关键字可忽略; ::: ```cpp class num_sequence{ public: virtual const char what_am_i() const { return “xxx\n”; } }; class Fibonacci:public num_sequence{ public: virtual const char what_am_i(){ return “xx” } };

Fibonacci b; num_sequence* pp=&b; cout<< pp->what_am_i();//输出会输出基类的。

  1. :::warning
  2. 上述的定义方法是错误的,并没有做到完全相同;<br />why会调用基类的函数呢?
  3. - 指针是基类的指针
  4. - 派生类中的函数并不被认为是基类虚函数的重写,而是被认为是新定义了一个虚函数;
  5. - 基类的指针若没有虚函数动态绑定的机制,只能访问到基类里面的的成员函数,因此会访问基类的who_am_i();
  6. :::
  7. :::info
  8. 有一种情况下返回值的可以不完全吻合——返回值是某个基类的形式(比如指针或者引用)
  9. :::
  10. ```cpp
  11. virtual num_sequence* clone()=0;
  12. //================================
  13. virtual Fibonacci *clone(){return new Fibonacci(*this);}

虚函数的静态解析

:::info 两种情况下虚函数机制并不会出现预期行为:

  • 基类的constructor/deconstructor
  • 直接使用基类对象而非指针和引用 ::: why?
    设想一种场景:派生类的构造时,会先调用基类的构造函数,若是在基类构造函数中出现虚函数,按照虚函数的机制,应该调用派生类所定义的那一份?but此时派生类的data member尚未完全初始化,容易错误;

    小结