必须要注意的 C++ 动态内存资源管理(一)——视资源为对象
必须要注意的 C++ 动态内存资源管理(一)——视资源为对象 一.前言
所谓资源就是,一旦你用了它,将来必须还给系统。如果不这样,糟糕的事情就会发生。C++ 程序中最常见使用的资源就是动态分配内存(如果你分配了内存却忘记归还它,就会导致内存泄漏)。但是内存只是你必须管理的众多资源之一。其他常见的资源还有:文件描述器(file descriptors)、互斥锁(mutex locks)、图形界面中的字体和笔刷、数据库连接、以及网络sockets。无论哪种资源,重要的是,如果你不再使用它时,必须将它还给系统。 二.先举个栗子
假设我们在做一个RPG小游戏,主人公Player在游戏中获得不同buff从而更换不同的武器,假定这里我们的武器就只有三种:Fist(拳头),Knife(刀),Gun(抢)。
然后这三种武器继承自 class Weapon 基类。
那么我们可以使用一个工厂函数(factory function)来提供我们不同的武器: Weapon* createWeapon(…) ;
当你程序如此设计的时候,那么你的工厂类就主要负责生产了,而createWeapon的调用端就要有责任对获取的武器资源进行释放。举例如下: void changeWeapon(params)
{
Weapon* oldWeapon = playerWeapon;
playerWeapon = createWeapon(params);
...
delete oldWeapon;
} 以上代码看起来妥当,但在若干情况下,可能导致该函数释放oldWeapon——或许因为”…”中的某个过早的return语句。如果这样一个return语句被执行;又或者是因为”…”中有异常抛出;这些情况发生吃,那么控制流一定就不会触及到delete语句;而之前申请的内存(oldWeapon)就无可避免的泄露了。
当然了,谨慎的编写程序可以防止这一类错误。但是有个问题是必须值得思考的,随着业务逻辑的更改,这段代码很可能会在时间渐渐过去之后被修改。一旦软件开始接受维护,很有可能会有某些人添加return语句或者continue语句而未能全然领悟它对函数资源管理策略造成的后果。
这时候,我们需要将资源来视作一个对象来看。当构造初始化的时候获取资源,当析构销毁的时候释放资源。而析构函数是依赖C++的自动调用机制,这样我们就可以确保资源被释放。 以对象管理资源 ——————Effective C++ 条款13 三.资源对象
有了前面的解释,我们现在大概能够对为什么需要将资源当对象来看待有了理解。 下面我们来简单来介绍如何实现:
先将资源封装成类,完成资源的初始化加载,和释放。
template<typename T>
class res_ptr
{
public:
typedef T _myType;
typedef T* _myPType;
res_ptr(_myPType p = nullptr) :pointer(p){ }
~res_ptr(){ delete pointer; }
private:
_myPType pointer;
}; 现在我们可以用上面这个模板类来管理上面的指针。不过,上面的代码还没有完成。
在资源管理中,有时候会出现这样的语句:
res_ptr<T> p1; ... res_ptr<T> p2 = p1; 也就是赋值操作,在不同的场景中赋值操作可能有不同的含义(有时候不一定是赋值,可能是函数传参,函数返回) 1.如果是图片类的资源,在赋值的时候应该是资源的拷贝。
2.如果是文件、临接设备这样的资源,在赋值的时候应该是资源支配权的转移。
3.如果是数据库连接,网络sokets这样的资源,在赋值的时候应该是增加资源的引用数,而当引用数为0的时候释放资源。
所以,以上不同的类型也决定着类中的拷贝控制函数。 关于以上三种情况如何实现拷贝控制函数,我们留到下节继续介绍。
https://blog.csdn.net/y1196645376/article/details/53005803
必须要注意的 C++ 动态内存资源管理(一)——视资源为对象的更多相关文章
- 必须要注意的 C++ 动态内存资源管理(二)——指针对象简单实现
必须要注意的 C++动态内存资源管理(二)——指针对象简单实现 四.拷贝类型的资源 上节我们说过,对于图片类型的资源我们有时候往往采用拷贝(如果对于那种公共图片,可能采用唯一副本,提供 ...
- 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱
必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针. 在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...
- 必须要注意的 C++ 动态内存资源管理(六)——vector的简单实现
必须要注意的 C++ 动态内存资源管理(六)——vector的简单实现 十六.myVector分析 我们知道,vector类将其元素存放在连续的内存中.为了获得可接受的性能,vetor ...
- C++ Primer 5th 第12章 动态内存
练习12.1:在此代码的结尾,b1 和 b2 各包含多少个元素? StrBlob b1; { StrBlob b2 = {"a", "an", "th ...
- 动态内存管理---new&delete
动态内存管理 动态对象(堆对象)是程序在执行过程中在动态内存中用new运算符创建的对象. 因为是用户自己用new运算符创建的.因此也要求用户自己用delete运算符释放,即用户必须自己管理动态内存. ...
- C++动态内存new和delete(超详细)
C++动态内存new和delete C++动态内存是C++灵活.炫酷的一种操作.学好它,能让自己编程逼格上一个level. 在学习动态内存之前,我们先要了解C++是怎么划分内存的: 栈:在函数内部声明 ...
- c++动态内存管理与智能指针
目录 一.介绍 二.shared_ptr类 make_shared函数 shared_ptr的拷贝和引用 shared_ptr自动销毁所管理的对象- -shared_ptr还会自动释放相关联对象的内存 ...
- spark on yarn模式下内存资源管理(笔记1)
问题:1. spark中yarn集群资源管理器,container资源容器与集群各节点node,spark应用(application),spark作业(job),阶段(stage),任务(task) ...
- 【转】Linux C动态内存泄漏追踪方法
原文:http://www.cnblogs.com/san-fu-su/p/5737984.html C里面没有垃圾回收机制,有时候你申请了动态内存却忘记释放,这就尴尬了(你的程序扮演了强盗角色,有借 ...
随机推荐
- 编译heartbeat出现的问题
如报 cc1: warnings being treated as errors pils.c:245: error: initialization fromincompatible pointer ...
- mysql终止当前正在执行的sql语句
show processlist;找出你要停止的语句然后找出你要终止的语句的idkill 248
- Codeforces F. Vus the Cossack and Numbers(贪心)
题目描述: D. Vus the Cossack and Numbers Vus the Cossack has nn real numbers aiai. It is known that the ...
- php的希尔排序
算是改进了的插入排序, 从性能时间上来看,也确实更有改进. 但比起php内置的功能,性能还有十倍之差呢 <?php /** * 原理:把排序的数据根据增量分成几个子序列,对子序列进行插入排序, ...
- myBatis框架之入门(四)
Mybatis多表管理查询 多表关联关系分析: 多表关联:至少两个表关联.分析多表关系的经验技巧:从一条记录出发,不要从表整体去分析,比如分析A表和B表关系,A表中的一条记录对应B表中的几条记录,如果 ...
- ARTS-week4
Algorithm 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的.示例:输入:1->2->4, 1->3->4输出:1->1 ...
- 【CLAA系列】CLAA 通讯过程
名词: MSP:中兴服务器 CS:客户服务器,也就是我们的服务器 GW:网关,这里默认是中兴的网关 Chip:芯片,这里特指包含了Lora标准通讯模块,且针对CLAA做过特殊优化的芯片. Lora:L ...
- nginx和ftp搭建图片服务器
一.需要的组件 图片服务器两个服务: Nginx(图片访问): 1.http服务:可以使用nginx做静态资源服务器.也可以使用apache.推荐使用nginx,效率更高. 2.反向代理 实现 负载均 ...
- gitlab修改ip
gitlab 修改ip的两种方式: 修改/etc/gitlab/gitlab.rd 里面的#external_url 'http://gitlab.example.com' 为ip地址,然后重新构建- ...
- django-发送文件
客户端授权密码”,勾选“开启”,弹出新窗口填写手机验证码. settings.py配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBac ...