2013-07-27 44 views
0

例如,我有一個類如何在構造函數中給成員unique_ptr一個默認值?

class A 
{ 
public: 
    // argument with default value is too long, any better way 
    A(std::unique_ptr<int> data = std::unique_ptr<int>(new int(10))) 
     : mData(std::move(data)) 
    {} 

    // Is r-value better? Is the following code okay? 
    A(std::unique_ptr<int>&& data = std::unique_ptr<int>(new int(10))) 
     : mData(data) 
    {} 

private: 
    std::unique_ptr<int> mData; 
}; 
+3

那麼你可以有一個默認的構造函數:'A():mData(new int(10)){}' – Borgleader

+0

你想要一個較短的代碼嗎?第二個構造函數將只接受r值,並且數據將被複制,而不是像在第一個構造函數中那樣顯式移動到mData –

回答

3

乍一看,似乎你可以這樣做:(即統一初始化

A (std::unique_ptr<int> data = {new int(10)}) 
    : mData(std::move(data)) 
{} 

注意使用大括號然而,這不起作用(不編譯),因爲unique_ptr接受指針的構造函數被聲明爲explicit,這就排除了它在這裏的使用。你可以做

一件事是這樣的:

A (int * data = new int(10)) 
    : mData (data) 
{} 

也就是說,接受正常的指針,並從中構建您的會員。而且你也不需要移動它(雖然std::move仍然是推薦的)。

這一個確實編譯和工作,但它有一個致命的缺陷,即使你接管了傳入的所有權指針(你要去delete它),你沒有在你的界面中顯示這種行爲。所以,這個新的界面將比以前的界面更少。

另一種方式是寫一個快捷功能模板,像這樣:

template <typename T> 
std::unique_ptr<T> uptr (T * v) 
{ 
    return std::unique_ptr<T>(v); 
} 

然後,你的構造變爲:

A(std::unique_ptr<int> data = uptr(new int(10))) 
    : mData(std::move(data)) 
{} 

但在我看來,這不是多大的改進。

然而,如果這種特定的使用情況是你的整個問題,爲什麼不繼續和定義一個默認的構造函數和單參數的構造是這樣的:

A() 
    : mData (new int (10)) 
{} 

/*explicit*/ A (std::unique_ptr<int> data) 
    : mData(std::move(data)) 
{} 

這僅僅是比較明智​​的。 (請注意,推薦explicit有一個好主意和良好的形式,但與您的問題無關,因此我已經評論了它。)

另外,您的第二個構造函數實際上並沒有移動任何東西。在這種情況下,r值引用類型不起作用。總之,由於data有一個名稱,它不再是一個r值,儘管它的類型仍然是r值的參考。

相關問題