C++中虚函数和纯虚函数

总结一下虚函数和纯虚函数到底是个什么东西

在了解虚函数之前要知道C++继承是怎么回事儿


虚函数

废话不多说, 直接上代码:

#include <iostream>

class Base
{
public:
    virtual void f(float x) { std::cout << "Base::f " << x << "\n"; }
    void g(float x){ std::cout << "Base::g " << x << "\n"; }
};

class Derived : public Base
{
public:
    void f(float x){ std::cout << "Derived::f " << x << "\n"; }
    void g(float x){ std::cout << "Derived::g " << x << "\n"; }
};

int main(int argc, char const *argv[])
{
    Derived A;
    Base* pb = &A;
    Derived* pd = &A;
    // 
    std::cout << "Virtual Test:\n";
    A.f(3.14);
    pb->f(3.14);
    pd->f(3.14);
    // 
    std::cout << "\nNon-Virtual Test:\n";
    A.g(3.14);
    pb->g(3.14);
    pd->g(3.14);
    return 0;
}

解释一下这段代码在干啥:

  • Base类定义两个函数: f, g, 两个函数的功能一模一样, 都是打印传入的x, 区别在于f是前有virtual关键字, 即f是虚函数
  • Derived类继承自Base类, 定义两个函数: f, g, 两个函数的功能一模一样, 都是打印传入的x
  • main函数定义了一个Derived类A, 然后分别用一个Base类的指针(小贴士: C++中基类指针可以指向派生类, 但派生类指针不能指向基类)和一个Derived类的指针指向它
  • 三者统一传入参数3.14, 观察A本身和有无virtual关键字的函数打印结果对比

运行结果:

Virtual Test:
Derived::f 3.14
Derived::f 3.14
Derived::f 3.14

Non-Virtual Test:
Derived::g 3.14
Base::g 3.14
Derived::g 3.14

对比可知:

Base* pb = &A;这个类调用的是派生类Derived中的f自身的g, 也就是说虽然pb指向的是一个派生类, 但是由于pb自己有明确的函数g的实现,

于是就会覆盖A中的实现

而使用虚函数就会避免这个问题, 虚函数相当于留了一个插槽, 如果派生类中有实现了基类中的虚函数, 则直接调用派生类中最早的实现


纯虚函数

纯虚函数只存在于基类中, 纯虚函数的写法为在虚函数末尾加上= 0

class Base
{
    virtual f(float x) = 0;
}

在写完这句声明之后, 不能有任何实现(编译器会报错的), 因为纯虚函数的意义就是给后面的派生类留一个接口

纯虚函数是在告诉程序员:"如果你想使用这个类的派生类, 你就必须在派生类中实现预留的纯虚函数!"

posted @ 2022-06-28 14:31  EvanZone  阅读(40)  评论(0编辑  收藏  举报