Effective C++读书笔记(9)

来源:互联网 发布:linux编程书籍推荐 编辑:程序博客网 时间:2024/06/06 08:40

条款13:以对象管理资源

将动态分配的资源放进对象内,成为对象的成员变量,我们便可以依赖于C++的析构函数自动调用机制确保资源被释放。

智能指针:

用智能指针可以有效缓解C++的内存回收问题:C++没有自动内存回收机制,每次new出来的堆内存都要手动delete(std中的auto_ptr即是智能指针)。

对于编译器来说,智能指针实际是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放由它管理的堆内存。智能指针通过通过‘->'返回对象的引用,用以操作对象(也可以用(*my_smart_object).访问对象)。访问智能指针本身对象的方法用'.'操作符。

访问智能指针包含的裸指针用get()函数。由于智能指针是一个对象,所以if(my_smart_object)永远为真。要判断智能指针的裸指针是否为空要用if(my_smart_object.get())来判断。

智能指针包含了reset()方法,如果不传递参数(或者传递Null),则智能指针释放当前所管理的堆内存。如果传递一个对象,则智能指针会释放当前对象来管理新传入的对象。

auto_ptr属于STL,在memory.h中。其能够方便的管理单个堆内存对象。但有以下注意事项:1、不能使用“operator=”操作符,因为复制操作符会使左侧智能指针完全夺取了原先指针的内存管理权,导致原先智能指针悬空。2、release()函数不会释放对象,仅归还所有权。

许多资源被动态分配于heap中而后被用于单一区块或者函数中。它们应在离开那个区块或函数前被释放,此时应用auto_ptr。

以对象管理资源的两个关键思想:获得资源后立即放进管理对象内(Resource Acquisition Is Initialization,RAII);管理对象运用析构函数确保资源被释放。

auto_ptr有个性质:若通过copying函数复制它会使其变成NULL,而复制所得的智能指针将取得资源的唯一拥有权。因此不能将auto_ptr应用与STL容器中(STL容器要求其元素能正常复制)。

可采用“引用计数型智能指针”(RCSP)。RCSP也是智能指针,持续跟踪共有多少对象指向某个资源,并在无人指向他时自动删除该资源。但无法打破环状应用。(tr1::shared_ptr)

环状应用的例子:

#include<string>#include <iostream>#include <boost/shared_ptr.hpp>#include <boost/weak_ptr.hpp>class parent;class children;typedef boost::shared_ptr<parent> parent_ptr;typedef boost::shared_ptr<children> children_ptr;class parent{public:    ~parent() { std::cout <<"destroying parent\n"; }public:    children_ptr children;};class children{public:    ~children() { std::cout <<"destroying children\n"; }public:    parent_ptr parent;};void test(){    parent_ptr father(new parent());    children_ptr son(new children);    father->children = son;    son->parent = father;}void main(){    std::cout<<"begin test...\n";    test();    std::cout<<"end test.\n";}

运行该程序可以看到,即使退出了test函数后,由于parent和children对象互相引用,它们的引用计数都是1,不能自动释放,并且此时这两个对象再无法访问到。

auto_ptr和tr1:shared_ptr在析构函数中都做的是delete,而不是delete[],因此都不能应用于动态分配的数组(可以用vector和string取代array)。
0 0
原创粉丝点击