2013-02-19 38 views
3

在Ubuntu上使用Eclipse/gcc與-std = C++ 0x進行開發。使用隊列對象切片

我似乎有對象切片的問題,這不屬於我在這裏看到的其他問題。我有一個非常簡單的基類/子類繼承模型。基類有這明顯的孩子實現一個純虛函數:

class Parent{ 
public: 
    Parent(); 
    virtual ~Parent(); 
    virtual void DoStuff() = 0; 
}; 

class Child : public Parent{ 
public: 
    Child(); 
    virtual ~Child(); 
    virtual void DoStuff(); //Child can have "grandchildren" 
}; 

我要的是有一個隊列,我可以通過一個輔助線程存儲這些對象進行處理。我知道我應該存儲指針,否則我會保證切片。因此,在執行此類別(「處理器」),我有:

typedef queue<Parent*> MYQUEUE; //#include <queue> 
static MYQUEUE myQueue; 

//Call this after creating "Child c;" and passing in &c: 
void Processor::Enqueue(Parent* p) 
{ 
    myQueue.push(p); 
} 

void* Process(void* args) //function that becomes the worker thread 
{ 
    while(true) 
    { 
     if(!myQueue.empty()) 
     { 
      Parent* p = myQueue.front(); 
      p->DoStuff(); 
      myQueue.pop(); 
     } 
    } 
    return 0; 
} 

那麼,什麼情況是,程序崩潰,說:「叫純虛方法」,彷彿繼承/多態性不能正常工作正確。我知道繼承設置正確,因爲我測試我證實了這個作品:

Child c; 
Parent* p = &c; 
p->DoStuff(); 

任何指導極大讚賞!

+1

你是否已經開始使用調試器? – 2013-02-19 16:58:24

回答

2

如果您將對象傳遞給工作線程,則無法在堆棧上創建它。當工作線程調用它時,父線程可能會離開該函數並銷燬該對象。您需要在父線程中動態分配它(可能通過new),並且在完成它之後,只在工作線程中釋放它(delete)。

另外需要注意的是,如果父級能夠在工作人員運行時排隊,那麼您需要鎖定隊列訪問權限。

+0

你是對的 - 當重構舊代碼時,我沒有注意到內存不是「新」的。是的,控制隊列中的訪問是我列表中的下一個任務。 – dcdunne 2013-02-19 17:19:03

0

該錯誤表示在調用點p指向的對象的類型爲Parent。它如何得到這種方式取決於你沒有顯示的代碼。