2013-08-22 25 views
11

Mục đích của tôi là giữ đối tượng std::thread làm thành viên dữ liệu và khởi tạo nó khi cần.
Tôi không thể thực hiện việc này (như trong mã của tôi bên dưới) vì hàm tạo bản sao của lớp std::thread bị xóa. CÒn cách nào khác để thực hiện việc này không?Có thể định nghĩa std :: thread và khởi tạo nó sau này không?

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

Chuyển 'this' thay vì dereferencing' * this'. –

Trả lời

3

Vấn đề của bạn là một vấn đề khác - bạn đang chuyển trường hợp MyClass vào thành viên đó là MyClass chức năng mong đợi. Đơn giản chỉ cần thay đổi DoDiskJobThread() như thế này (không chỉ tới đích this):

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); 
    } 
} 

Bạn đã nhận được lỗi vì *this dẫn đến cố gắng để sao chép MyClass vào chức năng thread, và ctor bản sao của lớp học của bạn sẽ bị xóa (vì đó của std::thread bị xóa). Tuy nhiên, các hàm thành viên CopyThreadMoveThread yêu cầu một con trỏ làm đối số đầu tiên (ẩn).

Live demonstration

+0

+1, vâng, tôi không nhận thấy sự thật rằng anh ta đang đi qua '* this' thay vì 'this', bạn nói đúng; –

+1

Toán tử '=' không cho phép gán một đối tượng chuỗi mới cho biến 'DiskJobThread'. Tôi nhận được lỗi này: 'lỗi C2678: nhị phân '=': không tìm thấy toán tử nào có toán hạng bên trái của loại 'const std :: thread' (hoặc không có chuyển đổi được chấp nhận)' – hkBattousai

+0

@hkBattousai Không có 'const std :: thread' trong mã bạn đã đăng (và bạn có thể thấy trên ideone rằng thay đổi của tôi hoạt động). Đăng mã thực của bạn. – Angew

10

Làm thế nào để gói nó trong con trỏ?

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

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

Edit: Và vâng, những người khác đã đề cập đến nó và tôi không cảm thấy cần phải thêm nó ở đây, nhưng để tránh nhiều downvote đóng cọc, tôi sẽ nói nó: Bạn đang đi qua *this và không this do đó sao chép một phiên bản của lớp học của bạn. (Các sự cố phát sinh do không thể sao chép được. Hãy vượt qua this và bạn nên làm tốt.)

+1

Bây giờ 'thread_ptr' không thể sao chép được nữa và không thể di chuyển ít hơn« DiskJobThread' ban đầu, mặc dù ... –

+1

@KerrekSB Có, nhưng nếu mục tiêu chỉ để khởi tạo sau, tôi _think_ nó không phải là một vấn đề; –

+1

-1: Vấn đề không phải là với initialising 'std :: thread' (như sử dụng một chuyển nhượng nhiệm vụ op đó là tốt), do đó, điều này không trả lời câu hỏi. – Angew

4

Bạn không thể khởi các đối tượng thread sau khi nó được tạo ra; theo định nghĩa, khởi tạo xảy ra khi một đối tượng được tạo ra. Nhưng bạn có thể sử dụng swap để di chuyển đối tượng chuỗi vào một đối tượng khác:

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 
&hl=vi
+0

Chỉ cần những gì tôi đang tìm kiếm _std :: swap (thread1, thread2) _ – Charlie

+0

Nó không hoạt động. ném lỗi này: C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ VC \ include \ xmemory0 (611): lỗi C2280: 'std :: thread :: thread (const std :: thread &)': cố gắng tham chiếu đến hàm đã xóa 1> C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ VC \ include \ thread (70): xem khai báo 'std :: thread :: thread' 1> Chẩn đoán này xảy ra trong trình biên dịch tạo ra chức năng 'Abc :: Abc (const Abc &) – codeLover

+0

@codeLover - vấn đề là trong lớp của bạn 'Abc' mà dường như có một' std :: thread' như là một thành viên dữ liệu .. 'std :: thread' không có thể sao chép, do đó, lớp học của bạn phải vô hiệu hóa việc xây dựng bản sao hoặc có một trình tạo bản sao bằng cách nào đó có ý nghĩa trong việc cố gắng sao chép đối tượng chuỗi đó. –

Các vấn đề liên quan