2013-02-19 66 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。它如何得到这种方式取决于你没有显示的代码。