2015-07-01 92 views
2

我需要從具有帶一個參數的構造函數的類創建一個std::unique_ptr。我找不到有關如何操作的參考資料。這裏是不能編譯的代碼示例:C++如何從構造函數上需要參數的類創建std :: unique_ptr

#include <iostream> 
#include <string> 
#include <sstream> 
#include <memory> 

class MyClass { 

    public: 
     MyClass(std::string name); 
     virtual ~MyClass(); 

    private: 
     std::string myName; 
}; 

MyClass::MyClass(std::string name) : myName(name) {} 
MyClass::~MyClass() {} 

class OtherClass { 

    public: 
     OtherClass(); 
     virtual ~OtherClass(); 

     void MyFunction(std::string data); 

     std::unique_ptr<MyClass> theClassPtr; 
}; 

OtherClass::OtherClass() {} 
OtherClass::~OtherClass() {} 

void OtherClass::MyFunction(std::string data) 
{ 
    std::unique_ptr<MyClass> test(data); <---------- PROBLEM HERE! 
    theClassPtr = std::move(test); 
} 

int main() 
{ 
    OtherClass test; 
    test.MyFunction("This is a test"); 
} 

的錯誤的方式有關I'm初始化std::unique_ptr,在我的代碼中指出。

原始碼和錯誤可以在here找到。

感謝您幫助我解決這個問題。

+0

使用'std :: make_unique',它將參數轉發給構造函數。 –

+0

我試過了,但是我不能編譯它...... seens認爲std :: make_unique在C++ 11上不受支持...... – Mendes

+0

你能顯示沒有用的代碼嗎? –

回答

3

你可以這樣做:

std::unique_ptr<MyClass> test(new MyClass(data)); 

或者,如果你有C++14

auto test = std::make_unique<MyClass>(data); 

但是:

在所提供的例子,沒有必要創建一個臨時變量,你可以使用類成員的reset方法:

theClassPtr.reset(new MyClass(data)); 
+0

或者,您可以簡單地刪除'test'變量,然後使用'theClassPtr.reset(new MyClass(data));'來代替。 –

+0

@RemyLebeau謝謝你,我忘記了原來的問題,謝謝你指出。現在修復。 – Galik

1
#include <memory> 
... 

int main() 
{ 
    std::string testString{ "Testing 1...2....3" }; 
    auto test = std::make_unique<MyClass>(testString); 
    return 0; 
} 
1

它基本上是一個疏忽。您需要:

#include <memory> 

namespace std 
{ 

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

將函數添加到std是非法的。把它放在'notstd'中。 – Yakk

+0

如果它是非法的,那麼每個C++標準都是非法的。 –

+0

@DavidSchwartz:也許你的意思是「每個C++標準*庫實現*都是非法的」? –

0

C++ 14自帶std::make_unique。它在C++ 11中被省略了。

寫它自己很容易:

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

現在這樣使用它:

auto foo = notstd::make_unique<MyClass>(string); 

會讓你的獨特PTR你。

這種模式有幾個優點。首先,它會從「用戶代碼」中刪除與delete沒有配對的new,這讓我很開心。其次,如果您調用一個需要2個不可識別的ptrs的函數,那麼在拋出異常的情況下,上述可以避免泄漏。

因爲向std注入新功能,所以在notstd中加入了這個標準(不需要診斷)。

相關問題