可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时,
基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,
而不是基类中定义的成员函数(只要派生类改写了该成员函数)。
若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都
会调用基类中定义的那个函数。

class A
{
public:
     virtual void print(){cout<<"class A print func"<<endl;}
     void run(){cout<<"A class have run func"<<endl;}
    
};
class B:public A
{
public:
    void print(){cout<<"class B print func"<<endl;}

    void run(){cout<<"C class have run func"<<endl;}

};
class C:public B
{
public:
    void print(){cout<<"class C print func"<<endl;}

    void run(){cout<<"C class have run func"<<endl;}

};

void fun(A* a)
{
    a->print();

    a->run();
}

int main()
{
    C c;
    fun(&c);

}

 

运行结果:


class C print func

A class have run func

虚函数是动态绑定的基础。
是非静态的成员函数。
在类的声明中,在函数原型之前写virtual。
virtual 只用来说明类声明中的原型,不能用在函数实现时。
具有继承性,基类中声明了虚函数,派生类中无论是否说明,同原型函数都自动为虚函数。
本质:不是重载声明而是覆盖。
调用方式:通过基类指针或引用,执行时会 根据指针指向的对象的类,决定调用哪个函数。