使用队列进行对象切片

时间:2013-02-19 16:56:05

标签: c++ object-slicing

使用带有-std = c ++ 0x的Eclipse / gcc在Ubuntu上进行开发。

我似乎遇到了对象切片的问题,这不属于我在这里看到的其他问题。我有一个非常简单的基类/子类继承模型。基类有一个纯虚函数,显然是子实现的:

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

非常感谢任何指导!

2 个答案:

答案 0 :(得分:2)

如果要将对象传递给工作线程,则无法在堆栈上创建它。当工作线程调用它时,父线程可能已经离开该函数并销毁了该对象。您需要在父线程中动态分配(可能通过new)并在完成后在工作线程中仅释放(delete)。

另外请注意,如果父项能够在工作人员运行时将作业入队,则需要锁定队列访问。

答案 1 :(得分:0)

错误意味着p在呼叫点指向的对象具有类型Parent。如何通过这种方式取决于你没有显示的代码。