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

什么是虚函数?

定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数。
用途:实现多态性,通过指向派生类的基类指针,访问派生类中同名覆盖成员函数

什么是纯虚函数?

定义:在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加"=0"。

用途:为了方便使用多态特性,尝尝需要在基类中定义虚拟函数;在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。

什么是抽象类?

定义:包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。

用途:将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。

什么是动态绑定?

动态绑定(动态联编、推迟联编):声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数。由于编写代码的时候并不能确定被调用的是基类的函数还是派生类的函数,所以被称为“虚函数”,即一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。

其他

(0) C++多态(polymorphism)是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),称为重写。

(1) 如果未声明为虚函数,企图通过基类指针调用派生类的非虚函数是不行的。

(2) C++规定,当一个成员函数被声明为虚函数时,其派生类中的同名函数都自动成为虚函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在每一层声明该函数时都加virtual,使程序更加清晰。

(3) 如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。

(4) 声明纯虚函数的类是一个抽象类,这样的类不允许实例化。定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的派生类必须实现这个函数,否则编译无法通过。

代码如下:

#include<iostream>
using namespace std;

// 抽象类,无法实例化
class test2
{
public:
    // 纯虚函数
    virtual void fun2() = 0;
};

// 继承抽象类,重写父类虚函数
class B :public test2
{
public:
    virtual void fun2()
    {
        cout << "fun2" << endl;
    }
};

class test
{
public:
    // 虚函数
    virtual void fun()
    {
        cout << "virtual class test" << endl;
    }
};

class A:public test
{
public:
    // 重写父类的虚函数
    void fun()
    {
        cout << "virtual class A" << endl;
    }
};

int main() 
{
    // 多态:父类指针指向子类对象
    shared_ptr<test> t1 = make_shared<A>();
    t1->fun();

    // 父类指针指向自身
    t1 = make_shared<test>();
    t1->fun();

    // 子类实现父类的纯虚函数
    B b;
    b.fun2();
    return 0;
}

运行结果:

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