2015-12-18 58 views
3

我有一個問題,我不明白。我有一個產生線程的類。一切都好。我做了一個新的對象 - 一切OK。如果我將它們存儲在一個向量中以遍歷我的代碼,則無法編譯。我使用g ++ 4.9 i686。我做了以下簡短的程序,它完全模仿了真正的代碼相當廣泛的問題。 如果有人可以澄清或遞給我一個對我的寵物項目很好的解決方案,因爲我堅持這樣做。代碼如下:錯誤:使用刪除的函數'test :: test(const test&)C++與矢量相結合

#include <thread> 
#include <string> 
#include <iostream> 
#include <vector> 

class test 
{ 
public: 
    test(); 
    void setstring(std::string s); 
    ~test() { } 
    void runThread() { m_thread = std::thread(&test::print, this); } 
    void stop() {on=false;m_thread.join(); } 
private: 
    std::string s; 
    bool on=false; 
    std::string m_data; 
    std::thread m_thread; 
    void print(); 
}; 

test::test(){s="";m_data="";} 

void test:: print() { std::cout << "I'm running" << '\n'; on = true; 
    while(on==true){std::cout << m_data << '\n';} 
} 

void test:: setstring(std::string s){m_data = s;} 

int main() 
{ 
//this works 
test one ; 
one.setstring("thread running"); 
one.runThread(); 
getchar(); 
one.stop(); 
std::cout << "I've stopped" << '\n'; 

std::vector<test> testvec; 
test *tst; 
tst= new test; 
//testvec.push_back(*tst); //FAILES TO COMPILE 
delete tst; 
} 
+0

你有後''權的反引號,不知道這是應該被刪除的問題 – Czipperz

+0

構造函數和析構函數,什麼也不做。 – Czipperz

回答

6

您使用的版本std::vector::push_back需要可複製的對象,並且您的類不可複製。其原因是,std::thread非可複製

thread(const thread&) = delete;

因爲它是不能夠複製你的類的默認拷貝構造函數被刪除。

添加默認testtestvec可以使用std::vector::emplace_back

testvec.emplace_back(); 

或通過調用構造臨時中push_back

,它將調用的r值參考超載push_back()

您還需要擺脫構造函數和析構函數因爲它們阻止了你需要正確工作的移動構造函數的自動創建。一個經驗法則是,如果你的類只包含POD類型或POD類型類型(自己照顧的對象),那麼你不需要創建任何構造函數,因爲編譯器提供的構造函數可以工作。

+0

我明白現在的理由 - 但我無法解決它我一直使用刪除函數'std :: thread :: thread(const std :: thread&)你可以嘗試編譯它嗎? – ZoOl007

+0

因爲有一個用戶提供的析構函數,所以'test'沒有隱式生成的移動構造函數。 @ ZoOl007將不得不編寫move-constructor和move-assignment操作符,或者(最好)刪除析構函數。 –

+0

'vector :: emplace_back'仍然需要MoveAssignable,因爲它可能導致重新分配 –

2

正如其他人所說,push_back要求對象是可複製的,但是您可以使用std::move將線程移動到向量中,避免複製。

testvec.push_back(std::move(*tst)); 
+0

也不起作用 - 我錯過了一些東西 - 你可以嘗試編譯它嗎?它需要鏈接器和-std = C++ 11 -pthread標誌的pthread – ZoOl007

相關問題