- shared_ptr不等于shared_ptr的类型:如下面的例子:pInv是shared_ptr不是Investment*
#include <iostream> #include <memory> #include <mutex> // #include <pthread.h> using namespace std; class Investment { public: void printfxx() { std::cout << "printfxx\n"; } }; std::shared_ptr<Investment> pInv(new Investment); int daysHeld(const Investment* pi) { } int main() { daysHeld(pInv); //编译失败:pInv是shared_ptr不是Investment* std::cout << "get wait\n"; std::cin.get(); }
- 隐式转换:但是shared_ptr重载了operator->和opereator*两个操作符,所以这种操作是可以的。
int main(){ pInv->printfxx(); (*pInv).printfxx(); }
- 显式转换:通过get,拿到共享指针pInv中的Investment*指针
int main(){ pInv.get()->printfxx(); }
以shared_ptr作为资源管理类,通过显式/隐式转换对外提供接口,所以对于自己设计的资源管理类,也可以考虑类似的实现。但需根据情况选择显示还是隐式转换。
-
显示转换隐藏不了细节,隐式转换增加使用风险
#include <iostream> #include <memory> #include <mutex> // #include <pthread.h> using namespace std; class FontHandle {}; class Font { public: //隐式转换函数 operator FontHandle()const { return f; } private: FontHandle f; }; int main() { FontHandle tmp = Font(); //将类Font通过operator()重载,实现Font到FontHandle的隐式转换 std::cout << "get wait\n"; std::cin.get(); }
总结
- APIs往往要求访问原始资源,所以每一个RAII类应该提供一个“取得其所管理的资源”的办法
- 对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便