C++中构造函数和析构函数能否是虚函数

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

前言

在C++的类中,当我们用到多态的时候会把基类中的某个函数定义为虚函数,然后在子类中重新实现这个函数。在此过程中我们引发了一个讨论,基类中的构造函数和析构函数是否也可以定义为虚函数呢?下面我们一起来分析一下。

构造函数

首先我们来看一下构造函数的定义:
类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。该类对象被创建时,编译系统为该对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作。

由定义我们知道构造函数主要是为了在创建对象时完成初始化工作,初始化可以从一下几个方向来考虑:

  1. 存储空间
    我们知道一旦在类中定义了虚函数就会有一个虚函数表 vtable,vtable 存储于对象的内存空间中,通过虚指针 vptr来确认调用哪一个函数。
    如果构造函数是虚的,那么就需要通过 vtable来调用,但是此时对象还未实例化,即内存空间还没有,是无法找到vtable的;
  2. 实际使用
    虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数就没有实际意义;
  3. 实际含义
    在调用构造函数时还不能确定对象的真实类型(因为子类会调父类的构造函数),而且构造函数的作用是提供初始化,在对象生命期只执行一次,不是对象的动态行为,没有必要成为虚函数;
  • 总结:构造函数不需要是虚函数,也不允许是虚函数,因为创建一个对象时我们总是要明确指定对象的类型。

析构函数

析构函数的定义:
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。析构函数通常用于释放在构造函数或在生命期内获得的资源(如动态分配的内存)。从广义上讲,析构函数的作用并不仅仅限于释放资源方面,它可以执行任意操作,用来执行对象即将被撤销之前程序员所期待的任何操作。

在使用多态的时候,编译器总是根据类型来调用类成员函数。但是一个派生类的指针可以安全地转化为一个基类的指针。这样删除一个基类的指针的时候,C++不管这个指针指向一个基类对象还是一个派生类的对象,调用的都是基类的析构函数而不是派生类的。如果你依赖于派生类的析构函数的代码来释放资源,而没有重载析构函数,那么会有资源泄漏。

  • 总结: 析构函数可以为虚函数,而且当使用基类指针或引用来调用子类时,最好将基类的析构函数声明为虚函数,否则可以存在内存泄露的问题。
    原文作者:lucky-billy
    原文地址: https://blog.csdn.net/qq_34139994/article/details/105252837
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞