EC++学习笔记(三) 资源管理

条款13:以对象管理资源

资源包括:动态分配内存、文件描述符、网络socket、互斥锁、数据库连接

把资源放进对象内,可以依赖c++的"析构函数自动调用机制"确保资源被释放
智能指针: 是一个"类指针"对象,引用计数型指针,当引用对象数为0时,自动删除该资源

std::shared_ptr<Class> pClass(new Class);

 

每一笔资源都在获得的同时立刻被放进管理对象中

 

条款14:在资源管理类小心copy行为

RAII:资源获取即初始化,资源在构造函数期间获得,析构函数期间释放

class Lock {
    public:
        explicit Lock(Mutex* pm) : mutexPtr(pm) {
            lock(mutexPtr);
        }

        ~Lock() {
            unlock(mutexPtr);
        }
    private:
        Mutex* mutexPtr;
};

 

当一个RAII对象被复制时:
a.禁止复制:将copy函数声明为 private 且只声明不实现
b.引用计数:std::shared_ptr
shared_ptr 允许指定所谓的"删除器"(一个函数或函数对象),当引用计数为0时便被自动调用

class Lock{
public:
    explicit Lock(Mutex* pm)
        : mutexPtr(pm, unlock) { lock(mutexPtr.get()); }
private:
    std::shared_ptr<Mutex> mutexPtr;
};

 

c.复制底部资源,深度拷贝
d.慎用:auto_ptr,转移底部资源的拥有权,资源的拥有权会从被复制对象转移到目标对象

 

条款15:在资源管理类中提供对原始资源的访问

 

std::shared_ptr<Class> pClass(new Class);

现在某个函数要求访问原始资源:
int func(const Class *pClass);
如果我们调用:int result = func(pClass);
此时错误,因为func函数需要的是 Class* 指针(原始指针),而不是std::shared_ptr<Class>

shared_ptr提供一个get成员函数,用来执行显式转换,会返回智能指针内部的原始指针(的拷贝)

 

条款16:成对使用 new 和 delete 时要采用相同形式

如果 delete 加上中括号,delete 便认定指针指向一个数组,否则认定指针指向单一对象

string* stringPtr1 = new string;
string* stringPtr2 = new string[100];

delete stringPtr1;    //删除单一对象
delete []stringPtr2;  //删除由对象组成的数组

 

条款17:以独立语句将newed对象置入智能指针
int func(std::shared_ptr<Widget> (new Widget), func1());

 

在调用func之前,编译器必须创建代码,做一下三件事:
1.调用func1()
2.执行 new Widget
3.调用shared_ptr的构造函数
c++编译器并未指定这3件事的执行次序

如果编译器按 2--->1--->3 的次序执行
当执行func1出现异常时, new Widget返回的指针并未成功置入 shared_ptr内,可能引发资源泄露

解决方法:以单独语句将newed对象置入智能指针内

std::shared_ptr<Widget> pw(new Widget);
func(pw, func1());

 

posted @ 2013-11-26 14:10  skyline09  阅读(393)  评论(0编辑  收藏  举报