C++如何在构造函数和析构函数中调用虚拟函数

 更新时间:2023年08月02日 09:09:04   作者:lk_HIT  
这篇文章主要介绍了C++如何在构造函数和析构函数中调用虚拟函数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

C++构造函数和析构函数中调用虚拟函数

C++构造器可以为虚拟函数吗?

不行。

因为构造器调用的时候会设置当前类的虚表地址,然后如果构造函数本身为虚拟函数,那么调用构造函数就需要提前访问虚表,此时虚表指针还没有指向虚表,就没法访问虚表。

构造函数中可以调用虚拟函数吗?

可以。

但是调用虚拟函数就是调用跟调用普通函数效果一样。

因为子类在创建的时候是先调用父类的构造器,父类的构造器先设置好父类的虚表地址,然后再执行构造器中的代码,然后在回到子类构造器,先将虚表地址替换为子类的虚表地址,然后执行子类构造器的代码。

因此如果在父类构造器中调用虚函数,那么此时是从父类的虚表中查找函数地址,查找到的还是父类的虚函数地址。因此会调用父类的虚函数,而不会调用子类的虚函数。

析构函数中可以调用虚拟函数吗?

可以。

但是调用虚拟函数跟调用普通函数没啥区别。

因为析构的时候先执行子类的析构函数,再执行父类的析构函数,在执行当前类的析构函数的时候会先将虚表地址设置为当前类的虚表地址,然后再从虚表里查找函数地址,因此找到的只能是当前的虚函数的地址。

父类的析构函数为什么要为虚函数?

因为如果父类析构函数不为虚函数,那么当对象析构的时候只会调用指针当前类型的析构函数,不会调用父类或者子类的析构函数,会导致资源泄漏。

如果父类的析构函数为虚函数,那么子类的析构函数在析构的时候会先调用子类的析构函数,再调用父类的析构函数。这样子就不会存在资源泄漏。

注:

(1)将子类和父类构造器和析构器调用串起来是编译器实现的

(2)子类和父类都有自己的虚表。子类或者父类的构造器和析构器在最开始都是将虚表设置为当前类的虚表。然后才真正调用构造函数和析构函数里的代码。

C++构造函数和析构函数的调用顺序

1、构造函数的调用顺序 

基类构造函数、对象成员构造函数、派生类本身的构造函数  

2、析构函数的调用顺序

派生类本身的析构函数、对象成员析构函数、基类析构函数(与构造顺序正好相反) 

3、特例 

  • 局部对象,在退出程序块时析构
  • 静态对象,在定义所在文件结束时析构
  • 全局对象,在程序结束时析构 
  • 继承对象,先析构派生类,再析构父类 
  • 对象成员,先析构类对象,再析构对象成员
#include "stdafx.h"
#include <iostream>
using namespace std;
class  Clock
{
public:
    Clock()
    {
        cout << "clock的构造函数" << ",";
    }
    ~Clock()
    {
        cout << "clock的析构函数" << ",";
    }
};
class Date
{
public:
    Date()
    {
        cout << "date的构造函数" << ",";
    }
    ~Date()
    {
        cout << "date的析构函数" << ",";
    }
};
void main()
{
    Clock c;
    Date d;
    system("pause");
}

在使用构造函数和析构函数时,需要特别注意对它们的调用时间和调用顺序。

在一般情况下,调用析构函数的次序正好与调用构造函数的次序相反:最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。

可以简记为:先构造的后析构,后构造的先析构,它相当于一个栈,先进后出

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C语言实现推箱子游戏的代码示例

    C语言实现推箱子游戏的代码示例

    这篇文章主要介绍了C语言实现推箱子游戏的代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 基于Matlab实现绘制3D足球的示例代码

    基于Matlab实现绘制3D足球的示例代码

    这篇文章主要为大家详细介绍了如何利用Matlab实现绘制3D足球,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下
    2022-11-11
  • C语言单链表遍历与求和示例解读

    C语言单链表遍历与求和示例解读

    我们在学习编程的过程中,虽然有些语法很简单,但是我们还是要做多题。不做题是发现不了问题的,发现问题我们就可以“对症下药”,进行查漏补缺了。刷题可以先从简单题开始刷,熟练之后再做一些可以提升自己能力的题
    2022-07-07
  • 详解C++ 前置声明

    详解C++ 前置声明

    这篇文章主要介绍了C++ 前置声明的相关资料,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下
    2020-09-09
  • C++ Array容器的显示和隐式实例化详细介绍

    C++ Array容器的显示和隐式实例化详细介绍

    这篇文章主要介绍了C++中Array容器的隐式实例化和显式实例化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • C语言 makefile学习及实现实例

    C语言 makefile学习及实现实例

    这篇文章主要介绍了C语言 makefile学习及实现实例的相关资料,需要的朋友可以参考下
    2017-03-03
  • C++ sdl实现渲染旋转视频的方法分享

    C++ sdl实现渲染旋转视频的方法分享

    一般情况下播放视频时不需要旋转,但是如果是移动端录制的视频有时会出现rotate参数,且视频宽高也是互换的。所以本文为大家准备了利用sdl实现渲染旋转视频的方法,需要的可以参考一下
    2022-12-12
  • 一文带你学习C++析构函数

    一文带你学习C++析构函数

    在C++中,析构函数是一种特殊类型的成员函数,用于在对象生命周期结束时被自动调用,本文我们将介绍C++析构函数的一些重要知识点,并提供相应代码示例,需要的朋友可以参考下
    2023-05-05
  • C语言实现贪吃蛇游戏(单人版)

    C语言实现贪吃蛇游戏(单人版)

    这篇文章主要为大家详细介绍了C语言实现贪吃蛇游戏单人版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • C C++算法题解LeetCode1408数组中的字符串匹配

    C C++算法题解LeetCode1408数组中的字符串匹配

    这篇文章主要为大家介绍了C C++算法题解LeetCode1408数组中的字符串匹配示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10

最新评论