2012-07-27 118 views
11

是否有可能編寫一個智能指針,將對象本身分配給其構造函數 - 而不是開發人員必須調用new?換句話說,而不是寫:爲什麼智能指針不能在構造函數中爲我調用new()?

std::unique_ptr<myClass> my_ptr(new myClass(arg1, arg2))

...一個可以寫:

std::smarter_ptr<myClass> my_ptr(arg1, arg2)

是語言的語法能夠表達這個的?這會是可取的嗎?可怕?我想特別防範這種錯誤的(我做了我自己,當然):

myFunction(std::unique_ptr<myClass>(new myClass()), std::unique_ptr<myClass>(new myClass()))

...哪些風險泄漏如果第二分配較遲者爲準對象第一次分配和投在第一個物體安全地放入其智能指針之前。但是一個更聰明的指針實際上會讓這個安全嗎?

+2

@Joe:這是一個問題;在使用任何結果初始化一個智能指針之前,生成的代碼很可能執行兩個'new'表達式;在這種情況下,如果第二次投擲,你會得到泄漏。 – 2012-07-27 13:47:23

+2

@Joe:你錯了。 'tmp1 = new myClass(); tmp2 = new myClass(); arg1 = std :: unique_ptr(tmp1); arg2 = std :: unique_ptr(tmp2); myFunction(arg1,arg2);'是完全合法的執行順序。 – 2012-07-27 13:47:31

+1

夠公平的,我試圖證明自己不正確。謝謝。 – Joe 2012-07-27 13:48:06

回答

2

這實質上是同一個問題,需要std::findstd::find_if。您不能從new myClass(arg1)案例中的shared_ptr現有案件中區分此案。參數個數相等,並且arg1可以有任何類型。

因此,你需要另外一個名字,那就是make_shared

+0

這很容易通過標籤類型解決,比如'shared_ptr (std :: inplace_args,args ...)',這也是標準將分配器參數傳遞給某些可變參數函數的原因。 – Xeo 2012-07-27 13:54:07

+0

@Xeo,真的,所以'make_shared'不是必需的,它可以按照OP的建議來完成,但是'make_shared (args ...)'無論如何都少輸入:) – 2012-07-27 13:56:10

+0

@Xeo:的確。有很多可能的解決方案,而C++並不完全一致。 – MSalters 2012-07-27 13:57:52

11

一般情況下,這不能用智能指針的構造函數中完成;關於是否應該使用指針參數來初始化智能指針還是轉發以創建新對象,將存在不明確的地方。

它可以用一個工廠函數來完成,例如:

template <typename T, typename... Args> 
std::unique_ptr<T> make_unique(Args&&... args) { 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

如果您使用std::shared_ptr,那麼你可以使用std::make_shared。這也提供了只需要一個內存分配的優點,其中std::shared_ptr<T>(new T)將需要一個用於該對象而另一個用於共享引用計數。

+0

當然,只有當功能添加到現有的智能指針時,模糊纔會存在,否?我仍然好奇他們爲什麼沒有像'make_shared()'開始執行;有一種不對稱會讓我的智能指針調用delete,但不得不自己調用new。 – bythescruff 2012-08-12 12:48:34

相關問題