C++之在资源管理类中提供对原始资源的访问(15)---《Effective C++》

来源:互联网 发布:淘宝店铺上架宝贝数量 编辑:程序博客网 时间:2024/06/05 00:20

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

C++中设计资源管理类特别方便,通过利用资源管理类来处理资源之间的所有交互,不用直接操作原始资源,避免了内存泄露等一系列问题,但这一定是好的吗?如果一个函数只要求使用原始资源呢?放心,强大的C++永远不会这么轻易狗带,我们先来看看面临的问题,然后在来看C++给我们提供的解决方案:

std::trl::shared_ptr<Investment> pInv(createInvestment());//见条款13中的代码int daysHeld(const Investment* pi);//返回投资天数int days=daysHeld(pInv);//错误!

可以看到这样的代码直接报错了,根本通不过编译,因为daysHeld需要的是Investment*指针,你传给它的参数是类型为trl::shared_ptr管理的Investment的对象,因此这样编译器直接报错。
这时候你需要一个函数将RAII(Resource Acquisition is initialization)类对象转换为内部的原始资源(本类中的Investment*),C++提供了两种方式:
1)显示转换
trl::shared_ptr和auto_ptr都提供了一个get成员函数,用来执行显示转换,也就是它会返回只能指针内部原始资源指针(的复件):
int days=daysHeld(pInv.get());
2)隐式转换
就像所有智能指针一样,trl::shared_ptr和auto_ptr也重载了取值操作符(operator->和operator*),允许隐式转换至内部原始指针,如:

class A{public:    ...    void show() const;    ...};A* createA();std::trl::shared_ptr<A> s_a(createA());s_a->show();//利用operator->访问资源(*s_a).show();//利用operator*访问资源

由于有时候还是必须取得RAII对象内的原始资源,某些RAII class提供了一个隐式转换函数,

class FontHandle{class Font{public:    ...    operator FontHandle()const{        return f;    }    ...private:    FontHandle f;};

提供自己的代码:

#include <iostream>#include <string>using namespace std;class AA{public:    explicit AA(int xx) :xx(xx){    }    void show(){        cout << xx << endl;    }private:    int xx;};class A{public:    A(AA aa) :aa(aa){    }    operator AA()const{        return aa;    }private:    AA aa;};int main(){    AA aa(10);    A a(aa);    AA b = a;    b.show();    return 0;}

运行结果:
这里写图片描述
总结:
1)APIs往往要求访问原始资源(raw resources),所有每一个RAII class应该提供一个“取得其所管理之资源”的办法;
2)对原始资源的访问可能经由显示转换,一般而言显示转换比较安全,但隐式转换比较方便!

阅读全文
0 0
原创粉丝点击