虚函数和boost绑定奇怪的行为 [英] Virtual function and boost bind strange behavior

查看:127
本文介绍了虚函数和boost绑定奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux下编写的一段代码中看到了一个奇怪的行为,我想分享它,看看是否有人知道原因。
我有一个基类和一个派生类。在基类中我定义了一个虚方法,而在派生类中我重新定义了该方法,具有相同的签名。然后我用boost bind启动一个线程。下面是一个示例代码:

I saw a strange behavior in a piece of code I wrote under Linux, and I would like to share it to see if someone knows the cause of that. I had a base class and a derived class. In the base class I defined a virtual method, and in the derived class I redefined that method, with the same signature. Then I used boost bind to start a thread. Here's a sample code:

Class Base {
public:
    virtual void DoSomething();
    virtual void Init() = 0;
    ...
}

Class Derived : public Base {
public:
    void DoSomething();
    void Init();
    ...
}

在Derived类的Init方法中这样做:

In the Init method of the Derived class I did this:

 boost::thread *t = new boost::thread(boost::bind(&Base::DoSomething, this));

基类的DoSomething方法做了它的意思,派生类是一个空的方法,留在那里的错误。现在,当运行上面的代码时,大多数时候Base类的DoSomething在线程中执行,所以应用程序工作正常,而有时它不工作。经过一些调试,我注意到上面的错误,并删除了派生类的DoSomething解决了问题。在调试模式下使用Eclipse似乎总是调用派生类的DoSomething方法,而从控制台运行应用程序大多数时间,但不总是。有这种行为的原因吗?我的意思是,为什么有时绑定函数使用基类方法,有时同样的方法派生类?

The DoSomething method of the base class did what it was meant to do, while the same method of the derived class was an empty method, left there by mistake. Now, while running the code above, most of the times the DoSomething of the Base class was executed in the thread, so the application worked fine, while sometimes it did not work. After some debug I noted the mistake above, and removing the DoSomething of the derived class solved the issue. Using Eclipse in debug mode it seems that the DoSomething method of the derived class was always called, while running the application from the console worked most of the times, but not always. Is there a reason for this behavior? I mean, why sometimes the bind function used the base class method, and sometimes the same method of the derived class?

提前感谢

编辑以回应@pmr

这将很难显示完整的工作示例,我会尝试

It would be hard to show a full working example, I will try to show a bit how the classes are used.

首先我实例化一个Derived对象,然后在init函数中,用上面显示的初始化代码启动线程。 DoSomething有一个while循环在一个向量上迭代,但这不是我想的点。

First I instantiate a Derived object, then in the init function I start the thread with the initialization code shown above. The DoSomething has a while loop that iterates on a vector, but that's not the point I think.

void Derived::Init()
{
    ...
    boost::thread *t = new boost::thread(boost::bind(&Base::DoSomething, this));
}

void Base::DoSomething()
{
    while(true) {
        ...
    }
}

void Derived::DoSomething()
{
}

你可以在这段代码中看到Derived DoSomething方法是空的,所以有时我没有看到任何处理,而是发生在Base DoSomething函数中。

As you can see in this code the Derived DoSomething method was empty, so sometimes I did not see any processing, which instead took place in the Base DoSomething function.

推荐答案

我猜我发现了这种行为的原因:首先我调用了Base类构造函数中的线程构造函数。我认为这是问题,因为由于基本构造函数在派生的函数之前被调用,有时vtable被创建指向空派生函数,有时线程在创建vtable之前启动,因此bind函数使用基本方法,它做了它的意图。我想使用调试一些延迟被介绍,所以使用调试器线程总是绑定到派生类方法,导致错误的行为。此外,我尝试在init函数中移动线程创建,这样导出的函数总是被调用。

I guess I've found out the reason of this behavior: at first I called the thread constructor inside the Base class constructor. I think this is the problem, because since the base constructor was called before the derived one, sometimes the vtable was created pointing to the empty derived function, sometimes the thread was started before the vtable was created, thus the bind function used the base method, which did what it was meant for. I guess that using debug some delays were introduced, so using the debugger the thread was always bound to the derived class method, causing a wrong behavior. Also, I tried moving the thread creation inside the init function, and in that way the derived function is always called.

这篇关于虚函数和boost绑定奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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