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++设计模式之抽象工厂模式,本文要讲的抽象工厂模式,就是工厂方法模式的扩展和延伸,需要的朋友可以参考下
    2014-09-09
  • Visual Studio Code (vscode) 配置 C / C++ 环境的流程

    Visual Studio Code (vscode) 配置 C / C++ 环境的流程

    这篇文章主要介绍了Visual Studio Code (vscode) 配置 C / C++ 环境的流程,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • C语言自定义类型详解(结构体、枚举、联合体和位段)

    C语言自定义类型详解(结构体、枚举、联合体和位段)

    这篇文章主要给大家介绍了关于C语言中结构体、枚举、联合体和位段自定义类型的相关资料,分别介绍了结构体、枚举、联合体和位段等四种自定义类型,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-08-08
  • C语言计算日期差的方法示例

    C语言计算日期差的方法示例

    这篇文章主要介绍了C语言计算日期差的方法,结合具体实例形式分析了C语言针对日期转换、运算等相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • 解析C/C++中如何终止线程的运行

    解析C/C++中如何终止线程的运行

    本篇文章是对C/C++中如何终止线程运行的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C/C++中关于std::string的compare陷阱示例详解

    C/C++中关于std::string的compare陷阱示例详解

    这篇文章主要给大家介绍了关于C/C++中关于std::string的compare陷阱的相关资料,文中先对C/C++中的std::string进行了简单的介绍,通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • C++设计与实现ORM系统实例详解

    C++设计与实现ORM系统实例详解

    这篇文章主要为大家介绍了C++设计与实现ORM系统实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • C++演讲比赛管理系统实现流程实例

    C++演讲比赛管理系统实现流程实例

    这篇文章主要介绍了C++演讲比赛管理系统实现流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • ON_COMMAND_RANGE多个按钮响应一个函数的解决方法

    ON_COMMAND_RANGE多个按钮响应一个函数的解决方法

    这篇文章主要介绍了ON_COMMAND_RANGE多个按钮响应一个函数的解决方法,需要的朋友可以参考下
    2014-07-07
  • 浅谈C++ IO流

    浅谈C++ IO流

    这篇文章主要介绍了C++ IO流的相关资料,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08

最新评论