“纯虚拟方法”当实现boost :: thread wrapper接口 [英] "pure virtual method called" when implementing a boost::thread wrapper interface

查看:178
本文介绍了“纯虚拟方法”当实现boost :: thread wrapper接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小包装,它集中了相对于线程的内容:

 类线程{
protected:
boost :: thread * m_thread;

virtual void work()= 0;

void do_work(){
work();
}

public:
Thread():m_thread(NULL){}
virtual〜Thread(){
catch_up
delete m_thread;
}

inline void catch_up(){
if(m_thread!= NULL){
m_thread-> join();
}
}

void run(){
m_thread = new boost :: thread(boost :: bind(& Thread :: do_work,boost :: ref(* this)));
}
};

当我实现它时,请使用以下内容:

  class A:public Thread {
void work(){}
};

在:

 code> A a; a.run(); 



我有一个运行时终止,显示一个漂亮的纯虚拟方法。我认为这是boost :: bind参数,但我不知道如何说使用虚拟纯实现...



非常感谢。

尊敬的,



Mystère先生

解决方案

您的崩溃发生只有当您的程序立即退出:它调用类A的析构函数完成并调用线程的析构函数之前新开始的线程有机会预定。线程然后调用你的虚函数,但类A不再存在,所以它试图调用Thread的do_work(),它调用纯虚拟工作()。这是你的程序额外输出:

  run()started 
run()ended
〜A )开始
〜A()结束
〜Thread()开始
catch_up()开始
do_work()开始
纯虚拟方法



在标准方面,我认为这是未定义的行为,因为对象的生命周期已经结束(析构函数调用开始) ( boost :: ref(* this))用于从线程调用do_work()。



解决方案:让你的线程在你销毁对象之前执行:

  A a; a.run(); 
a.catch_up();

或者,如boost.thread文档所述,,Boost.Thread的用户必须确保引用对象比新创建的执行线程更长。


I have a small wrapper which centralize what's relative to threads :

class Thread {
protected:
    boost::thread *m_thread;

    virtual void work() = 0;

    void do_work() {
        work();
    }

public:
    Thread() : m_thread(NULL) {}
    virtual ~Thread() {
        catch_up();
        delete m_thread;
    }

    inline void catch_up() {
        if(m_thread != NULL) {
            m_thread->join();
        }
    }

    void run() {
        m_thread = new boost::thread(boost::bind(&Thread::do_work, boost::ref(*this)));
    }
};

When I implement it, say with the following :

class A : public Thread {
    void work() {}
};

At :

A a; a.run();

I got a runtime termination with a pretty "pure virtual method called" displayed. I think it's the boost::bind argument, but I don't know how to say "Use virtual pure implementation"...

Thanks aforehand.

Regards,

Mister Mystère

解决方案

Your crash happens only when your program exits immediately: it calls class A's destructor which finishes and calls Thread's destructor before the newly started thread had a chance to be scheduled. The thread then calls your virtual function, but class A no longer exists, so it attemps to call Thread's do_work(), which calls the pure virtual work(). Here's your program with extra outputs:

run() started 
run() ended
~A() started
~A() ended
~Thread() started
catch_up() started
do_work() started
pure virtual method called

Standard-wise, I think this is undefined behavior because the object's lifetime has already ended (destructor call began) when a reference to it (boost::ref(*this)) was used to call do_work() from the thread.

Solution: let your thread execute before you destruct your object:

A a; a.run();
a.catch_up();

Or, as boost.thread documentation says, "the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution."

这篇关于“纯虚拟方法”当实现boost :: thread wrapper接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆