C++浅析虚函数使用方法

 更新时间:2022年08月24日 16:20:14   作者:_拾贰_  
对C++了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。本文就将详细讲讲虚函数表的原理与使用,需要的可以参考一下

阐述虚函数作用和原理、纯虚函数和虚函数的区别。

一、虚函数

首先来看下面这一段代码,首先创建两个类,一个是Dog,另一个是Cat,他们有一个共同的属性:Run。在定义中每个动物都需要创建一个类,比较繁琐,所以在下面的例子中,我们可以把他们简化。

#include <iostream>
using namespace std;
class Dog{
public:
    void Run(){
        cout<<"Dog->Run"<<endl;
    }    
};
class Cat{
public:
    void Run(){
        cout<<"Cat->Run"<<endl;
    }
};
int main()
{
    Dog d;
    d.Run();
    Cat c;
    c.Run();
    return 0;
}

这里使用多态和虚函数,而Animal提供统一的接口,供子类使用,虽然代码繁琐,但提高了整个工程的可扩展性和灵活性。

在普通函数前加上关键字 virtual 构成虚函数,子类需要重写父类的虚函数,这样在调用的时候,会覆盖掉父类的虚函数 Run,去执行子类的Run。

#include <iostream>
using namespace std;
class Animal{
public:
    virtual void Run(){
        cout<<"Animal->Run"<<endl;
    }
};
class Dog :public Animal{
public:
    void Run(){
        cout<<"Dog->Run"<<endl;
    }    
};
class Cat:public Animal{
public:
    void Run(){
        cout<<"Cat->Run"<<endl;
    }
};
int main()
{
    Animal *ani;
    ani = new Dog;
    ani->Run();
    delete ani;
    ani = new Cat;
    ani->Run();
    delete ani;
    return 0;
}

结果如下:

所以在这里只需要修改ani的指向就可以实现不同方法。如果不存在虚函数,把Animal类的关键词virtual去掉会怎么样呢,显然,他们会默认实现父类Run的方法。

class Animal{
public:
    void Run(){
        cout<<"Animal->Run"<<endl;
    }
};

所以引入虚函数是为了实现动态多态,指向不同的子类来实现不同的方法。

二、虚函数与纯虚函数的区别

因为父类的函数可以不做任何操作,所以这里可以直接等于0;实现纯虚函数。

//虚函数
class Animal{
public:
    virtual void Run(){
        cout<<"Animal->Run"<<endl;
    }
};
//纯虚函数
class Animal{
public:
    virtual void Run()=0;
};

虚函数与纯虚函数的区别:

纯虚函数只是一个接口,只能供子类去重写实现方法。而虚函数在里面也可以去实现父类的功能。只需要指向父类的方法即可。

总结:虚函数在子类里面也可以不进行重写,但纯虚函数必须在子类去实现,如果把子类中的Run方法去掉,只留下父类中的纯虚函数,那么编译器会报错,这里大家可以试试。

三、动态多态

Animal内部的结构是什么样呢?这里有一个虚函数指针(vfptr)和虚函数表(vftable)。 指针(vfptr)指向虚函数表,在虚函数表(vftable)内记录着虚函数的地址,即Run函数的地址。

当子类的Dog去继承父类后,父类的虚函数表相应的也继承下来,子类也会保存一份和父类相同的。

注意!这时候如果发生重写,即子类重写了父类的虚函数,则子类的虚函数表会覆盖父类继承下来的虚函数表。但父类的虚函数表不会发生改变。

当父类的指针或者引用指向子类的对象时,就发生了多态。

下面的代码中是指向了Dog,所以会去Dog的虚函数表中找到相应的函数,在运行阶段发生了动态多态。

    Animal *ani;
    ani = new Dog;
    ani->Run();

到此这篇关于C++浅析虚函数使用方法的文章就介绍到这了,更多相关C++虚函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言数组越界引发的死循环问题解决

    C语言数组越界引发的死循环问题解决

    本文主要介绍了C语言数组越界引发的死循环问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 如何利用C语言位运算解决只出现一次的数字

    如何利用C语言位运算解决只出现一次的数字

    这篇文章主要给大家介绍了关于如何利用C语言位运算解决只出现一次的数字的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • C++ pair的用法实例详解

    C++ pair的用法实例详解

    这篇文章主要介绍了C++ pair的用法实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • 详解C语言中strpbrk()函数的用法

    详解C语言中strpbrk()函数的用法

    这篇文章主要介绍了详解C语言中strpbrk()函数的用法,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-08-08
  • C++ ofstream与ifstream详细用法

    C++ ofstream与ifstream详细用法

    ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间
    2013-07-07
  • C语言用函数指针实现一个特别的计算器

    C语言用函数指针实现一个特别的计算器

    函数指针是一个指针变量,它可以存储函数的地址,然后使用函数指针,下面这篇文章主要给大家介绍了关于C语言用函数指针实现计算器的方法,需要的朋友可以参考下
    2022-07-07
  • 详解C++ const修饰符

    详解C++ const修饰符

    const 是 constant 的缩写,const可以帮我们避免无意之中的错误操作,本文给大家介绍C++ const修饰符的相关知识,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-05-05
  • C++11新特性之变长参数模板详解

    C++11新特性之变长参数模板详解

    本文主要介绍了C++11变长参数模板,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • 解析在Direct2D中画Bezier曲线的实现方法

    解析在Direct2D中画Bezier曲线的实现方法

    本篇文章是对在Direct2D中画Bezier曲线的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 关于c语言逗号表达式的运算规则知识点

    关于c语言逗号表达式的运算规则知识点

    在本篇文章里小编给大家整理的是关于c语言逗号表达式的运算规则知识点,需要的朋友们可以学习参考下。
    2020-03-03

最新评论