2013-08-22 19 views
11

Amacım, std::thread nesnesini veri üyesi olarak tutmak ve gerektiğinde başlatmaktır.
Bunu yapamıyorum (aşağıdaki kodumda olduğu gibi) çünkü std::thread sınıfının kopya kurucusu silindi. Bunu yapmanın başka yolu var mı?Bir std :: thread tanımlamak ve daha sonra başlatmak mümkün mü?

class MyClass 
{ 
    public: 
     MyClass():DiskJobThread(){}; 
     ~MyClass(); 

     void DoDiskJobThread(); 

    private: 
     int CopyThread(const std::wstring & Source, const std::wstring & Target); 
     int MoveThread(const std::wstring & Source, const std::wstring & Target); 
     std::thread DiskJobThread; 
}; 

MyClass::~MyClass() 
{ 
    DiskJobThread.join(); 
} 

void MyClass::DoDiskJobThread() 
{ 
    std::wstring Source = GetSource(); 
    std::wstring Target = GetTarget(); 
    int m_OperationType = GetOperationType(); 
    if  (m_OperationType == OPERATION_COPY) 
    { 
     DiskJobThread = std::thread(&MyClass::CopyThread, *this, Source, Target); 
    } 
    else if (m_OperationType == OPERATION_MOVE) 
    { 
     DiskJobThread = std::thread(&MyClass::MoveThread, *this, Source, Target); 
    } 
} 
+2

Bu "hata" yerine "bunu" iletin. –

cevap

3

Senin sorunun başka bir şeydir - sen MyClass üye yerine ibrenin iplik içine MyClass bir örneğini geçiyoruz işlevler bekler. Basitçe şöyle DoDiskJobThread() değiştirmek (yapamaz this KQUEUE):

void MyClass::DoDiskJobThread() 
{ 
    std::wstring Source = GetSource(); 
    std::wstring Target = GetTarget(); 
    int m_OperationType = GetOperationType(); 
    if  (m_OperationType == OPERATION_COPY) 
    { 
     DiskJobThread = std::thread(&MyClass::CopyThread, this, Source, Target); 
    } 
    else if (m_OperationType == OPERATION_MOVE) 
    { 
     DiskJobThread = std::thread(&MyClass::MoveThread, this, Source, Target); 
    } 
} 
*this iplik fonksiyonu içine MyClass kopyalamaya çalışırken sonuçlandı çünkü hata alıyorum edildi ve sınıfınızın kopya ctor (silinir

o çünkü std::thread silindi). Ancak, üye işlevleri CopyThread ve MoveThread, yine de ilk (gizli) bağımsız değişken olarak bir işaretçi gerektirir.

+0

+1, evet, '' this 'yerine' 'this' geçmekte olduğu gerçeğini fark etmedim, haklısınız; –

+1

'=' operatörü, 'DiskJobThread' değişkenine yeni bir thread nesnesi atamaya izin vermiyor. Bu hatayı alıyorum: 'error C2678: binary '=': 'const std :: thread' türünde bir sol işleneni alan (veya kabul edilebilir bir dönüştürme yoktur) hiçbir işleç bulunamadı' ' – hkBattousai

+0

@hkBattousai' const yok Gönderdiğiniz kodda std :: thread' (ve değişimin çalıştığı ideone görebilirsiniz). Gerçek kodunuzu gönderin. – Angew

10

İşaretçide nasıl sarılır?

std::unique_ptr<std::thread> thread_ptr; 

// Look into std::make_unique if possible 
thread_ptr = std::unique_ptr<std::thread>(new std::thread(...)); 

Düzenleme: Ve evet, diğerleri söz ettim ve buradan ekleme ihtiyacını duymadığını, ancak daha fazla downvote kazıkları önlemek için, bunu söylerim: Sen geçiyoruz *this ve this değil, böylece sınıfınızın bir örneğini kopyalar. (. Problemler dışı copyable çünkü ortaya this geçmek ve gitmek iyi olmalıdır.)

+1

Artık 'thread_ptr' artık kopyalanamaz ve orijinal' DiskJobThread'den daha az hareketli değildir, ancak ... –

+1

@KerrekSB Evet, ancak hedef sadece daha sonra başlayacaksa, o bir problem olmamalı; –

+1

-1: Sorun, std :: thread'ın başlatılmasıyla ilgili değil (bu iyi bir hareket atamasını kullanır), dolayısıyla bu soruya cevap vermiyor. – Angew

4

Live demonstration Sen oluşturulduktan sonra iplik nesne başlatılamıyor; Tanım olarak, bir nesne oluşturulduğunda başlatma gerçekleşir. Ancak, bir iş parçacığı nesnesini diğerine taşımak için swap'u kullanabilirsiniz:

std::thread thr1; // no thread of execution 
std::thread thr2(my_function_object); // creates thread of execution 
thr1.swap(thr2); // thr1 is now running the thread created as thr2 
        // and thr2 has no thread of execution 
+0

Sadece ne arıyordum _std :: takas (thread1, thread2) _ – Charlie

+0

çalışmıyor. Bu hatayı atar: C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ VC \ include \ xmemory0 (611): hata C2280: 'std :: thread :: iş parçacığı (const std :: thread &)': denemesi \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ VC \ \ iplik (70) yer alır: 'std :: iplik :: iplik' 1 bildirimi bkz> Bu teşhis derleyici oluştu 1> C silinmiş bir işlev başvurusu oluşturulan işlev 'Abc :: Abc (const Abc &) – codeLover

+0

@codeLover - sorun sınıfının 'görünüşte bir veri üyesi olarak bir' std :: thread' olan Abc' içindedir .. 'std :: thread' değil kopyalanabilir, bu nedenle sınıfınız kopya yapımını devre dışı bırakmak zorundadır veya bir şekilde bu iş parçacığı nesnesini kopyalamaya çalışmaktan anlamlı olan bir kopya oluşturucuya sahip olmalıdır. –