网站首页 > 文章精选 正文
一、析构函数
析构函数,学习过C++的肯定都知道是做什么的。学习类知识环节时,构造函数和析构函数是必须要掌握的,可能大家都对这两个函数没啥太大的感觉,毕竟这个东西非常简单明了,即使后来有了所谓的“三五法则”,也只是扩展了知识,而没有什么高难的技术。但是大家是不是都有这么一种经验,越是简单的东西,往往越能在某些应用上产生一些想象不到的作用。
那么析构函数只是为了处理对象资源的回收,这种情况下,有没有也会有这种应用呢?
在前面的文章“C++内存分配的管理 ”中对内存的一些特定的分配情况进行过分析,其中就包含了析构函数的私有化。本文将对其进行更全面和深入的分析说明。
二、为什么要私有化析构函数
开发者都知道,一般情况下,构析函数是自动调用的或者说隐式调用的。那么,私有化析构函数,就意味着析构函数无法被自动调用了。有进才有出,同样,有出才会有进。否则不把资源给占满了啊。特别是在栈上创建对象,栈的空间都不会多大,所以遇到这种情况,编译器都会提供编译错误。当然如果在堆上调用delete析构时,同样也会出现此错误。这也是C++设计时为了保证对象的生命周期的完整性所做的安全控制。
但在某些场景下,开发者可能需要将对象创建在特定的内存空间或其它特定的情况,主要有:
1、不允许将对象在栈空间上创建
这个在前面的文章中分析过,此处不再赘述。
2、需要显示处理析构函数的场景
这种场景就比较多了,比如全局单实例的情况、需要显示调用析构函数的一些情况以及需要屏蔽第三方释放对象的一些场景等情况。
三、私有化析构函数的局限性
需要重点提醒大家的,私有化析构函数这种情况是一种非常特定的应用场景,大家一定要明白这是一种特例,而非常态。所以在应用时,除了一些明确应用的场景下,不要使用。
私有化析构函数的应用,有着很大的局限性需要引起开发者的注意:
1、资源泄露特别是内存资源的泄露
因为无法调用析构对象,那么对象中的各种资源如文件句柄等,尤其是分配的内存都可能无法回收,导致开发者常见的资源泄露问题。
2、自动调用析构函数的场景无法应用
最典型的就是智能指针,智能指针就是自动调用析构函数来回收资源,而私有化则屏蔽了这种调用。同样,私有化构析函数的类,也无法正常的继承。如果一定要实现,则需要自己的处理子类对父类私有析构函数的访问,大大增加了编程的复杂性和安全性。
四、私有化析构函数如何释放对象
既然析构函数已经私有化,但释放对象的空间是一种强需求,这种情况下如何达到释放对象的目的呢?
1、友元函数
虽然一直不推荐使用友元,但在这种特定的场景下,友元函数确实能达到对象资源回收的效果。
2、提供单独的公有接口函数来调用私有的析构函数
其实就是提供一个init函数供构造函数调用一样,开发者可以提供了一个destroy之类的公有函数,在这个函数中调用相关的delete函数,或者干脆直接的调用析构函数。
五、例程
根据前面的分析说明,看一下相关的例程:
class IDemo {
public:
IDemo(){}
~IDemo() {}
void delObj(IDemo*ins){
delete ins;
}
friend void destroyObj(IDemo* ins){
delete ins;
}
};
代码非常简单,不再分析。
五、总结
其实对大多数开发者来说,难其实并不是一个非常不容易接受的问题,因为大家都感觉难,就不难了。而且实际的应用场景下,真正能用到难的技术或者说高深的技术的时候并不多。但灵活性则是一种极为常见的应用。说到这儿,大家应该明白了,C++为什么让人感觉不好学习,一个重要的原因正是基于其灵活多变的技术应用。
正如本文中的这个私有化的析构函数应用,就体现了一种普遍应用中的特定场景下的灵活应用。在C++中,这种灵活多变的应用方式非常多,所以大家不要着急,慢慢来。从基础应用和灵活应用中不断对比分析,慢慢自己也就掌握了一些内在的逻辑,也就意味着C++的水平上升了一个层次。
猜你喜欢
- 2025-08-01 游戏里的 boss 每天都在干嘛?不寂寞吗?
- 2025-08-01 秋招C++八股--封装、继承、多态(持续更新)
- 2025-08-01 Qt QDebug格式输出、自定义类输出及重定向输出Log
- 2025-08-01 C++11:weak_ptr的设计哲学(观察而不拥有)
- 2025-08-01 C++20 新特性(24):模板访问权限和typename的放宽
- 2025-08-01 c++学习大纲总结
- 2025-08-01 C++学习教程_C++语言随到随学_不耽误上班_0基础
- 2025-08-01 程序员效率分享:加速C ++编译
- 2025-08-01 零基础学编程不知道如何下手,该怎么办
- 2025-08-01 C++常用知识点汇总(基础)
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)
- fmt.println (52)