首页 > 编程语言 >C++中的构造析构函数—2—虚析构函数

C++中的构造析构函数—2—虚析构函数

时间:2023-05-03 22:56:09浏览次数:65  
标签:析构 函数 object Dog Animal 虚析构 constructed

1. 构造函数不能定义为虚函数,每个对象的虚函数表指针是在构造函数中初始化的,因为构造函数没执行完,所以虚函数表指针还没初始化好。而析构函数可以定义为虚函数,也必须要定义为虚函数,否则在析构上无法体现出多态,导致子类的析构函数不会被调用,可能导致内存泄漏等风险。


2. 实验:

#include <iostream>

#define USE_VIRTUAL
#define OBJECT_DOG

class Animal {
public:
    Animal() {
        std::cout << "Animal object constructed !" << std::endl;
    };
    void Kill () {
        std::cout << "Kill Animal !" << std::endl;
    }
#ifdef USE_VIRTUAL
    virtual ~Animal() { //父类有 virtual 关键字修饰
        std::cout << "Animal object deconstructed !" << std::endl;
    }
#else
    ~Animal() { //父类无 virtual 关键字修饰
        std::cout << "Animal object deconstructed !" << std::endl;
    }
#endif
};

class Dog : public Animal {
public:
    Dog() {
        std::cout << "Dog object constructed !" << std::endl;
    }
    void Kill () {
        std::cout << "Kill Dog !" << std::endl;
    }
    ~Dog() { //子类有无 virtual 关键字修饰都行
        std::cout << "Dog object deconstructed !" << std::endl;
    }
};

#ifdef OBJECT_DOG
int main()
{
    Animal *p = new Dog();
    p->Kill();
    delete p;
}
#else
int main()
{
    Animal *p = new Animal();
    p->Kill();
    delete p;
}
#endif

实验结果:

//同时定义了 USE_VIRTUAL 和 OBJECT_DOG,可以看到构造和析构都正常:
# ./pp
Animal object constructed !
Dog object constructed !
Kill Animal !
Dog object deconstructed !
Animal object deconstructed !

//不定义 USE_VIRTUAL 只定义 OBJECT_DOG,可以看到Dog对象的析构函数没有被调用:
# ./pp
Animal object constructed !
Dog object constructed !
Kill Animal !
Animal object deconstructed ! //可以看到Dog对象的析构函数没有被调用!

 

标签:析构,函数,object,Dog,Animal,虚析构,constructed
From: https://www.cnblogs.com/hellokitty2/p/17369851.html

相关文章

  • 字符设备驱动-5.设备树函数
    1.设备树相关的头文件1.处理DTBof_fdt.h//dtb文件的相关操作函数,我们一般用不到,//因为dtb文件在内核中已经被转换为device_node树(它更易于使用)2.处理device_nodeof.h//提供设备树的一般处理函数,//比如of_property_read_u32(读取某个属性的u32值),//......
  • 使用volatility dump从内存中重建PE文件——IAT函数出错的使用impscan解决
            好了,书中,说了操作的步骤,我们再vol2里实验下。查看进程:PSD:\Application\volatility3-stable>python.\vol.py-f"D:\book\malwarecookbook-master\malwarecookbook-master\16\7\laqma.vmem\laqma.vmem"windows.pslistVolatility3Fram......
  • pandas drop、loc和iloc函数对数据框进行操作
    pandas.DataFrame.drop—从行或列中删除指定的标签参考:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.drop.html语法格式DataFrame.drop(labels=None, *, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise......
  • filp_open函数
    我对filp_open函数有疑问:我可以从IS_ERR函数获取错误号,但是我不理解错误号的含义。在哪里可以找到filp_open错误号定义?fptr=filp_open(...)if(IS_ERR(fptr)){  printk("%d\",PTR_ERR(fptr));}        printk("lydfilp_openerror%d\n",PTR_ERR(src......
  • 【实变函数】07 - 微积分基本定理
    1.有界变差函数1.1有界变差函数及性质我们已经看到,单调函数有着很好的微分性质,但单调函数又过于“简单”了,更一般的函数都会有上下起伏。那要做怎样的限定才能保证函数既够“简单”又够“一般”呢?现在来讨论“起伏之和”有限的函数。记\(f(x)\)是\([a,b]\)上的有限函数,并......
  • 【实变函数】08 - 广义测度和积分
    本篇我们将对测度做更一般的讨论,以将其推广到更大的范围。1.变数变换和L-S测度1.1变数变换我们知道,测度是一个集函数,也就是子集到实数的映射。如果定义两个基本空间的映射\(\varphi:\,X_1\toX_2\),就有可能建立两个测度空间的关联。具体来说,假定\(\varphi\)建立在两......
  • 【实变函数】03 - 可测函数
    上篇在\(\sigma\)-环上延拓了测度的概念,并讨论了实数轴上典型的可测集\(\mathbf{L},\mathbf{L^g},\mathbf{B}\)。这些理论精巧而有其独立性,但还需放到合适的领域里才能展现其本质和威力。\(\sigma\)-环是个普遍的代数结构,它的可列交并运算特别适用于需要级数运算的场合,这也将......
  • 自定义函数实现分组统计
    1.通过自定义的函数实现分组统计: 2.自定义函数,对索引进行修改取不同产品名称的数量: ......
  • 【实变函数】04 - 基于测度的积分
    1.有限有界积分1.1积分及存在性有了前两篇的铺垫,现在可以顺理成章地定义积分的概念了。和Riemann积分一样,定义要分成两步,先是在有限定义域的有界函数上,然后使用极限法推广到一般函数上。具体来说,设\(E\)是某测度空间的有限可测集(\(\mu(E)<\infty\)),\(f(x)\)是\(E\)上的有界......
  • 【实变函数】05 - 积分极限和乘积测度
    1.积分的极限积分与极限运算的交换,是数学分析中的重要工具。但在Riemann积分中,运算交换需要较强的条件,特别是麻烦的“一致收敛性”。然而“一致收敛性”并不是运算交换的必要条件,但是从Riemann积分的定义出发,却很难再有进一步的弱化条件。本篇你将看到,在基于测度的积分上,极......