C++面向对象编程之析构详解

 更新时间:2022年03月17日 10:27:14   作者:charlee44  
这篇文章主要为大家详细介绍了C++面向对象编程之析构,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

1. 概述

类的析构函数执行与构造函数相反的操作,当对象结束其生命周期,程序就会自动执行析构函数:

class ImageEx
{
public:
    ImageEx()
    {
        cout << "Execute the constructor!" << endl;
    }
    ~ImageEx()
    {
        cout << "Execute the destructor!" << endl;
    }
};
int main()
{
    ImageEx imageEx;
    return 0;
}

那么同样的问题来了,为什么要有析构函数呢?

2. 详论

2.1. 对象生命周期

在经典C++中,需要通过new/delete来手动管理动态内存。如果我们在类中申请一个动态数组,并且通过自定义的函数Release()来释放它:

class ImageEx
{
public:
    ImageEx()
    {
        cout << "Execute the constructor!" << endl;
        data = new unsigned char[10];
    }
    ~ImageEx()
    {
        cout << "Execute the destructor!" << endl;
    }
    void Release()
    {
        delete[] data;
        data = nullptr;
    }
private:
    unsigned char * data;
};
int main()
{
    {
        ImageEx imageEx;
        imageEx.Release();
    }
    return 0;
}

那么,当类对象离开作用域,结束生命周期之前,就必须显示调用一次成员函数Release(),否则就会造成内存泄漏:对象在调用析构函数之后,只会销毁数据成员data本身,而不是其指向的内存。

那么,一个合理的实现是,将成员函数Release()放入到析构函数:

class ImageEx
{
public:
    ImageEx()
    {
        cout << "Execute the constructor!" << endl;
        data = new unsigned char[10];
    }
    ~ImageEx()
    {
        Release();
        cout << "Execute the destructor!" << endl;
    }
private:
    unsigned char * data;
    void Release()
    {
        delete[] data;
        data = nullptr;
    }
};
int main()
{
    {
        ImageEx imageEx;       
    }
    return 0;
}

这样,当类对象离开作用域,结束生命周期之前,就自动通过析构函数,实现了动态数组的释放。好处是显而易见的:实现了类似于内置数据类型对象的生命周期管理,我们可以像使用内置数据类型对象一样使用类对象。

2.2. 不一定需要显式析构

在一些现代高级编程语言(C#、Java、Javascript)中,已经不用去手动管理动态内存,取而代之的,是其与操作系统的中间件(.net,jvm,浏览器)的GC(垃圾回收)机制。而在现代C++中,提倡通过智能指针(std::shared_ptr、std::unique_ptr、std::weak_ptr)来管理动态内存;对于动态数组,则使用标准容器std::vector则更好。在两者的内部都实现了前文提到的对象生命周期管理,在离开作用域后,通过析构函数自动释放管理的内存,无需再手动进行回收。

那么,一个显而易见的推论就出来了,如果我们在类中使用智能指针或者vector容器来替代new/delete管理动态内存,是不是就可以不用析构函数了?严格来说,是不用显式使用析构函数:

class ImageEx
{
public:
    ImageEx():
        data(10)
    {
        cout << "Execute the constructor!" << endl;        
    }
private:
    std::vector<unsigned char> data;
};
int main()
{
    ImageEx imageEx;      
    return 0;
}

实际上,并不是这个类不存在析构函数,而是编译器会为它生成一个合成的析构函数,在这个析构函数体中,什么也不用做。因为类中的动态内存,已经交由std::vector容器来管理。当类对象离开作用域调用析构函数之后,会销毁这个std::vector容器数据成员,进而触发其析构函数,释放其管理的内存。

2.3. 析构的必要性

根据上一节内容,不一定需要显式析构。因为现代C++的一些机制能够帮你自动管理动态内存。但是析构函数还是必要的,这是由于C++语言本身的性质决定的。作为C语言大部分内容的超集,需要兼容C语言手动管理内存的特性。更重要的是,现代操作系统几乎全部由C语言编写,与底层的交互不可避免的需要手动使用动态内存管理。

3. 总结

所以我们就能理解了,C++这门语言的设计哲学就是就是这样:既想要C语言的高性能,也想要高级语言高度抽象的特性。如果我们必须兼容C语言底层设计,那我们最好使用析构函数释放动态内存;否则多数情况下,我们应该使用智能指针或者stl容器来管理动态内存,从而避免显示使用析构函数。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!     

相关文章

  • C++中new/delete与malloc/free的区别小结

    C++中new/delete与malloc/free的区别小结

    本文主要介绍了C++中new/delete与malloc/free的区别小结, malloc、free是C中的库函数 new、delete 是C++当中的操作符,读者可以更好地理解C++中内存管理的方式和优势
    2023-08-08
  • C++11实现简易定时器的示例代码

    C++11实现简易定时器的示例代码

    这篇文章主要介绍了C++11实现简易定时器的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • C语言实现二叉树遍历的迭代算法

    C语言实现二叉树遍历的迭代算法

    这篇文章主要介绍了C语言实现二叉树遍历的迭代算法,包括二叉树的中序遍历、先序遍历及后序遍历等,是非常经典的算法,需要的朋友可以参考下
    2014-09-09
  • 基于VS2019配置opencv4.0的方法步骤

    基于VS2019配置opencv4.0的方法步骤

    这篇文章主要介绍了基于VS2019配置opencv4.0的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • C语言的合法标识符与整型详解

    C语言的合法标识符与整型详解

    这篇文章主要为大家详细介绍了C语言的合法标识符与整,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • OpenCV获取图像中直线上的数据具体流程

    OpenCV获取图像中直线上的数据具体流程

    对图像进行处理时,经常会有这类需求:客户想要提取出图像中某条直线或者ROI区域内的感兴趣数据,进行重点关注,怎么操作呢,下面小编通过实例代码介绍下OpenCV获取图像中直线上的数据,一起看看吧
    2021-11-11
  • C++二级指针和指针的引用

    C++二级指针和指针的引用

    这篇文章主要介绍了C++二级指针和指针的引用,下文举例实现形参指针改变实参指针所指向的对象,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-03-03
  • C++实现并优化异常系统

    C++实现并优化异常系统

    异常处理是C++的一项语言机制,用于在程序中处理异常事件,下面这篇文章主要给大家介绍了关于C++中异常的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • C语言转义字符实例详解

    C语言转义字符实例详解

    这里主要介绍了C语言的转义字符的知识,并附有示例代码,以便理解,希望对学习 C语言的同学有所帮助
    2016-07-07
  • 关于C++使用指针 堆和栈的区别分析

    关于C++使用指针 堆和栈的区别分析

    本篇文章小编为大家介绍,关于C++使用指针 堆和栈的区别分析。需要的朋友参考下
    2013-04-04

最新评论