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

虚函数

面向对象的核心是多态,而虚函数又是多态的核心,说虚函数之前得先说多态,什么是多态。说人话:父类类型的指针指向子类,然后用父类的指针调用子类的函数。但是有个问题,用父类指针调用的函数,无论什么类型都会执行的是父类中的方法。

#include <iostream>
using namespace std;

class AA {
public:
    void show() {
        cout << "调用父类AA的show()方法" << endl;
    }
};

class BB : public AA{
public:
    void show() {
        cout << "调用子类BB的show()方法" << endl;
    }
};

int main() {
    AA* a = new BB();
    a->show();
}

很明显,AA的指针指向了BB,但是运行的确实AA的方法

为了解决这个问题,就有了虚函数。让我们在AA的show方法前加virtual。先试一下

#include <iostream>
using namespace std;

class AA {
public:
    virtual void show() {
        cout << "调用父类AA的show()方法" << endl;
    }
};

class BB : public AA{
public:
    void show() {
        cout << "调用子类BB的show()方法" << endl;
    }
};

int main() {
    AA* a = new BB();
    a->show();
}

非常的明显,调用了BB的方法。

虚函数和非虚函数的区别

非虚函数实在编译时根据调用该函数的对象,引用或者指针的类型而确定的,第一次运行的程序当中,a的指针类型时AA, 所以才调用的是AA类中的show方法。

而虚函数是到运行时才能确定调用的是哪个函数,在程序运行阶段动态的选择合适的成员函数,如果在子类中有重写,就运行重写版本,如果没有就运行虚函数(父类版本)。

虚函数的工作原理

虚函数是通过一张虚函数表来实现的。简称VTable。在这个表中,主要是一个类的虚函数地址表,这个表解决了继承和覆盖的问题,就相当于与一个地图,指明了实际所应该调用的函数。

纯虚函数

纯虚函数是一种特殊的虚函数,在某些情况下,基类中不能对虚函数给出有意义的实现,把它声明 为纯虚函数。

举个例子:一个动物类,可以有猫,狗,老虎,狮子等。但是你用动物本身生成对象,就明显不合理。 就比如猫会爬树,但是不是所有动物都会爬树,为了防止直接用父类(动物类)去创建对象,就要用到纯虚函数。

#include <iostream>
using namespace std;

class animal {
public:
    virtual void  pashu() = 0;

class cat : public animal {
public:
    void pashu() {
        cout << "我是小猫,我会爬树" << endl;
    }
};


int main() {
    animal* a = new cat();
    a->pashu();

    animal* a = new animal();   // 直接报错

}

纯虚函数在基类中为派生类保留一个函数的名字,以便派生类它进行重定义。如果在基类中没有保 留函数名字,则无法支持多态性。 含有纯虚函数的类被称为抽象类,不能实例化对象,可以创建指针和引用。

派生类必须重定义抽象类中的纯虚函数,否则也属于抽象类。

纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎么实现他”

猜你喜欢

转载自blog.csdn.net/qq_35326529/article/details/128975709