2011-09-12 26 views
5

bản sao của: "pure virtual method called" when implementing a boost::thread wrapper interfacethúc đẩy chủ đề phá hủy đa hình

Tôi đang cố gắng tạo phiên bản hướng đối tượng nhiều hơn cho chủ đề bằng cách sử dụng các chuỗi tăng.

Vì vậy, tôi đã tạo ra một lớp Thread:

class Thread { 
public: 
    Thread() {} 
    virtual ~Thread() { thisThread->join(); } 

    void start() { thisThread = new boost::thread(&Thread::run, this); } 

    virtual void run() {}; 

private: 
    boost::thread *thisThread; 
}; 

lớp này tạo ra các chủ đề trong start() như thế này:

thisThread = new boost::thread(&Thread::run, this);

Vấn đề là khi tôi tạo ra một lớp mà ghi đè phương thức run(), phương thức run() từ Chủ đề được gọi theo chuỗi thay vì phương thức run() mới

ví dụ tôi có một lớp học kéo dài Ðề tài:

class CmdWorker: public Thread { 
public: 
    CmdWorker() : Thread() {} 
    virtual ~CmdWorker() {} 

    void run() { /* deosn't get called by the thread */ } 
}; 

khi tôi làm

Thread *thread = new CmdWorker(); 
thread.start(); //---> calls run() from Thread instead of run() from CmdWorker 

nhưng chỉ để được rõ ràng hơn:

thread.run(); calls the correct run from CmdWorker, (run() is virtual from Runnable) 

Bất cứ ý tưởng tại sao điều này xảy ra hoặc làm thế nào nó có thể được cố định?

LƯU Ý: Tôi tạo ra một chức năng (mà không có gì để làm với các lớp Thread)

void callRun(Thread* thread) { 
    thread->run(); 
} 

và thay đổi tạo thread để:

thisThread = new boost::thread(callRun, this); 

khi gỡ lỗi tôi nhận thấy rằng thread con trỏ trỏ đến một đối tượng thuộc loại Chủ đề thay vì CmdWorker

EDIT:

đang

testcase tại địa chỉ: http://ideone.com/fqMLFhttp://ideone.com/Tmva1

Object dường như được thái lát (nhưng điều này là kỳ lạ kể từ khi con trỏ được sử dụng)

không quản lý để thêm động lực để nó

+0

Câu hỏi này không rõ ràng với tôi! – Nawaz

+1

Không đủ mã. Tôi không thấy làm thế nào bạn sẽ sử dụng cấu trúc như vậy. –

+2

FYI 'std :: thread' đang đến. Điều gì chính xác là sai với 'boost :: thread'? – spraff

Trả lời

4

Câu trả lời là trong câu hỏi rằng:

"pure virtual method called" when implementing a boost::thread wrapper interface

Về cơ bản, khi đối tượng tăng :: chủ đề bắt đầu chạy, đối tượng nó được chạy chống lại có thời gian để bị xóa.

Bạn phải triển khai phương thức join mà bạn gọi thủ công trước khi hủy đối tượng.

+0

Tôi thấy ... dammit: D Tôi cần tìm giải pháp thay thế – Ha11owed

1

Bằng cách &Thread::Run trên một hàm không phải ảo, bạn đang buộc bất kỳ lớp nào xuất phát từ Thread để sử dụng hàm được chỉ định trong lớp cơ sở Thread. Hãy thử làm cho Thread :: Chạy một khoảng trống ảo và xem nếu đó sửa chữa vấn đề của bạn.

+1

chạy là ảo từ Runnable – Ha11owed

+0

Nhưng không phải từ Chủ đề. – Michael

+3

@Michael: Trong C++, 'virtual' được thừa hưởng từ lớp cơ sở, miễn là chữ ký của hàm thành viên khớp nhau (mà chúng làm trong trường hợp này); khai báo 'Thread :: run' là' virtual' sẽ thừa. – ildjarn

3

khi gỡ lỗi tôi nhận thấy rằng con trỏ thread được trỏ đến một đối tượng loại Chủ đề thay vì CmdWorker

Có lẽ đối tượng CmdWorker được thái lát (tức là sao chép theo giá trị) vào một đối tượng Thread nơi nào đó trong ma cua ban?

Bạn có nhận được cùng một hành vi với trường hợp kiểm tra tối thiểu không?

+0

vâng tôi nhận được cùng một hành vi với một testcase – Ha11owed

2

Từ đọc nội dung cập nhật của bạn, bạn đang gọi xóa trong chuỗi chính, trong khi chuỗi bắt đầu bằng chuỗi kia. Tùy thuộc vào cuộc đua giữa các destructor và gọi trình run, nó sẽ hoặc là:

  1. sụp đổ trước khi nó bắt đầu, bởi vì vtable là hoàn toàn bị phá hủy
  2. Gọi Chủ đề :: chạy (mà là thuần túy ảo, và tai nạn với một thunk ảo tinh khiết)
  3. gọi chức năng chính xác, đó là lớp có nguồn gốc chạy()

Nếu bạn thêm một cuộc gọi đến sleep(1) sau khi bạn gọi bắt đầu, nhưng trước khi bạn gọi delete, bạn sẽ thấy rằng nó hoạt động bạn mong đợi

+0

Tôi đã đơn giản hóa ví dụ và xóa mọi khóa + kiểm tra. cũng trong destructor tôi làm một tham gia() vì vậy nó chờ cho thread để kết thúc. như tôi đã đề cập trước khi chạy() từ chuỗi được gọi. – Ha11owed

+3

@ Ha11owed Nếu bạn thêm một tham gia vào destructor của 'Thread', sau đó bởi thời gian tham gia được gọi là, các lớp học có nguồn gốc nhất đã bị phá hủy, và các mục vtable cho nó không còn tồn tại. –

+0

Tôi hiểu bây giờ không nhận thấy rằng – Ha11owed

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