effective c++條款17:以獨立語句將newed物件置入智慧指標
阿新 • • 發佈:2018-11-02
假設有這麼一個函式process,它接收一個MyClass型別的指標與 一個函式,如果按下面的方式呼叫:
#include <iostream> #include <memory> using namespace std; class MyClass { public: MyClass(){} ~MyClass(){} }; void FunMyClass() { //... } void Process(std::tr1::shared_ptr<MyClass> pM, void funMyClass()) { //... } int main(void) { Process(new MyClass, FunMyClass); return 0; }
這是錯誤的,因為智慧指標shared_ptr的建構函式被宣告為explicit,也就是不支援隱式轉換,所以我們要顯示的對其進行轉換:
Process((std::tr1::shared_ptr<MyClass>)(new MyClass), FunMyClass);
我們之所以使用智慧指標是為了防止資源洩漏,但是這樣呼叫還有可能導致隱患的,為什麼呢?
在呼叫函式Process之前,編譯器需要先構造出函式的引數,對於Process函式來說,它需要做三件事:
1. 呼叫FunMyClass;
2. new MyClass;
3. 呼叫shared_ptr的構造;
對於java,C#等語言,引數構造的順序是固定的,然而對於c++來說,唯一確定的就是new MyClass會先於shared_ptr的構造,所以如果引數構造的順序如下:
new MyClass→呼叫FunMyClass→呼叫shared_ptr的指標
那麼一旦FunMyClass丟擲了異常,那麼new的空間不會被shared_ptr接收到,導致資源洩漏。
解決方法很簡單:
std::tr1::shared_ptr<MyClass> pm(new MyClass);
Process(pm, FunMyClass);
這樣資源就不會洩露了。