【C++】动态内存管理(二)以对象管理资源
来源:互联网 发布:云计算应用场景举例 编辑:程序博客网 时间:2024/06/13 21:34
为什么要用对象去管理资源?
考虑如下情况。
我们声明一个对象A:
class A {private: int value;public: A(int v):value(v) {}; A() { cout << "creat A" << endl; } ~A() { cout << "delete A" << endl; };};
然后在一个函数中使用:
void test() { A *a = new A(1); ...... delete a; }
可以看到,
new
和delete
中间还有很多的执行语句,如果在这些执行语句中,触发了一个条件导致了return
的提前出现,然后这个函数就会被提前中止,delete
就不会被执行。这看起来妥当,但在若干情况下,或许因为”…”中的某个过早的return语句。如果这样一个return语句被执行;又或者是因为”…”中有异常抛出;这些情况发生吃,那么控制流一定就不会触及到delete语句;而之前申请的内存就无可避免的泄露了。
当然了,谨慎的编写程序可以防止这一类错误。但是有个问题是必须值得思考的,随着业务逻辑的更改,这段代码很可能会在时间渐渐过去之后被修改。一旦软件开始接受维护,很有可能会有某些人添加return语句或者continue语句而未能全然领悟它对函数资源管理策略造成的后果。
这时候,我们需要将资源来视作一个对象来看。当构造初始化的时候获取资源,当析构销毁的时候释放资源。而析构函数是依赖C++的自动调用机制,这样我们就可以确保资源被释放。
—《Effective C++》
这会导致怎样的后果? a
指向的内存将没有任何方式可以进行访问,a
指向的对象将不会被正确的析构。而且,其依然占据着堆上的内存空间和其内部保存的指针指向的内存空间,这就导致了严重的内存泄漏和内存浪费
为了确保a指向的内存一定会被释放掉,我们需要将资源放进对象内部,然后当控制流离开test()
函数,该对象的析构函数就会被自动的调用然后去释放那些资源。
怎样去做?获得资源后立刻就将对象放进管理对象(这也被称作RAII
)。
我们试着去自己构造一个资源管理对象。
如下:
template<typename T> class Data { private: T* pointer; public: Data(const Data& d) :pointer(d.pointer) {}; Data() :pointer(NULL) {}; Data(T* p=NULL) :pointer(p) {}; ~Data() { delete pointer; } T& operator*() { return *(this->pointer); } };
可以看到,这是一个简单的保存数据内存的管理类,当析构的时候就会自动删除其管理的内存空间。
我还重载了其“*”
操作符,用以方便的资源操作。
下面是一个使用的示例:
void test() { Data<int>p(new int(3)); cout << *p << endl; }
在资源被拿出的一瞬间,我们就将这个资源放入了资源管理类中进行保存,由于p
存在于栈空间,所以当test()
结束的时候,p
就会被释放,其析构函数就会被调用。
所以无论是什么原因,p所管理的资源都会被成功的释放掉。
不同的设计也对应着不同的资源类型,当我们使用不同的资源管理类的时候要牢记这一点。
对于下面的三种类型,我们在写拷贝构造和赋值操作的时候就一定要注意不同的写法。
- 如果是普遍性的资源(如
string
、vector
),在赋值的时候应该是资源的拷贝。(生成资源副本进行拷贝)- 如果是文件、连接设备这样的资源,在赋值的时候应该是资源支配权的转移。(转移内部资源指针所指向的资源的所有权)
- 如果是
socket
这样的资源,在赋值的时候应该是增加资源的引用数,当引用数为0的时候释放资源。
对于这三种的类型如何实现拷贝的控制,我就单开一章描写
- 【C++】动态内存管理(二)以对象管理资源
- C++内存管理------>以对象管理资源(Effective C++)
- 以对象管理资源
- <Effective C++> (Item 13-15): 以对象管理资源
- (11)以对象管理资源
- 以对象来管理资源
- item13: 以对象管理资源
- C++以对象管理资源
- 【Effective c++】条款13:以对象管理资源
- 《Effective C++》学习笔记条款13 以对象管理资源
- Effective C++——》条款13:以对象管理资源
- Effective C++:条款13:以对象管理资源
- 《Effect C++》学习------条款13:以对象管理资源
- 读书笔记《Effective C++》条款13:以对象管理资源
- 【C++】动态内存管理
- 【C++】动态内存管理
- 【C++】动态内存管理
- unity动态资源内存管理
- PAT B1062. 最简分数
- Java:P12加解密方法封装
- iOS_捕捉JSAlert/confirm事件
- c++一些记录
- 2017多校训练第二场 hdu6047 Maximum Sequence(贪心)
- 【C++】动态内存管理(二)以对象管理资源
- javascript构造函数
- 关于Ajax提交后session里面为空的问题
- VC维理论
- 7-27日java基础学习笔记
- CMake与Make
- Redis入门之环境的搭建
- 从dedup说起之JS数组去重
- 【期望】几何分布的期望