1. 程式人生 > >effective c++條款17:以獨立語句將newed物件置入智慧指標

effective c++條款17:以獨立語句將newed物件置入智慧指標

假設有這麼一個函式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);

這樣資源就不會洩露了。