虚函数

定不定义

普通成员函数只要没用到可以不写定义,但虚函数只要在主函数被用到,所有父类和子类必须都定义该函数,因为编译器只有在运行时才能确定用到哪个函数

调用虚函数

指针或引用运行时解析

有两种类型:动态和静态。

这里有动态类型和静态类型,只有在运行时才知道动态类型。

Quote base;
print_total(cout, base, 10);  //调用Quote::net_price()

Bulk_quote derived;
print_total(cout, derived, 10);  //调用Bulk_quote::net_price()

普通类型编译时解析

只有一种类型:只有静态了。

如果我们通过普通类型调用虚函数,就只会调用静态类型的函数。

base = derived;   //动态和静态类型一致
base.net_price(20); //调用Quote::net_price

 调用普通函数

测试都是调用基类的函数。

虚函数重写叫覆盖,普通函数重写叫隐藏。

class Base
{
public:
    void f()
    {
        cout<<"Base"<<endl;
    }
};

class Derived: public Base
{
public:
    void f()   //报隐藏非虚函数
    {
        cout<<"Derived_f"<<endl;
    }

    void g()
    {
        cout<<"Derived_g"<<endl;
    }
};



int main() {

    Base base;
    Derived derived;

    Base *p = &base;
    p ->f();    //输出Base
    p ->g();   //xxx ,报class Base无此函数
 
    p = &derived;
    p ->f();  //输出Base
    p ->g();   //xxx ,报class Base无此函数

    return 0;

}

口诀-Primer537

普通函数普通类型静态时,虚函数指针或引用运行时,普通类型还是静态时。

只有虚函数和引用或指针这俩条件都满足,才会动态绑定。

关键字

virtual关键字的范围

只要声明为virtual,派生类就不用声明了。

虚函数叫覆盖,形参和返回值都要完全匹配。

override关键字

动机

有时我们写了相同名字的函数,但形参列表和想覆盖的虚函数不同,这时编译器视为新函数,但是其实是想覆盖,这是一个不小心的错误。可以加上override来帮助检查。

final关键字

既可以不让类继承,也可以不让函数覆盖

忽略虚函数机制

加上作用域就行。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章