虚拟功能,促进绑定的奇怪行为 [英] Virtual function and boost bind strange behavior

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

问题描述

我看到在一块code的我在Linux下写了一个奇怪的现象,我想和大家分享,看看是否有人知道的那个原因。
我有一个基类和派生类。在基类我定义的虚拟方法,并在所导出的I类重定义该方法中,具有相同签名。然后我用升压绑定启动一个线程。下面是一个示例code:

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

在派生类中我这样做的init方法:

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

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

的基类的DoSomething的方法,做了什么,它的意思做的,而派生类相同的方法是一个空方法,错误地离开了那里。现在,在运行上述code,同时,大部分的时间的基类的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.

首先,我实例化一个派生类对象,然后在init函数我先上图所示的初始化code中的线程。该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()
{
}

正如你可以在这个code派生DoSomething的方法看是空的,所以有时我没有看到任何处理,而不是发生在基地的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.

推荐答案

我想我已经找到了这种行为的原因:首先我叫基类构造函数里面的线程构造函数。我觉得这是问题,因为自基类的构造是派生的人之前叫,有时虚函数表的创建指向空的导出函数,有时线程创建的虚函数表之前启动,从而绑定功能使用的基本方法,它做了什么,它的意思了。我猜,使用调试一些延误相继出台,所以使用调试器线程总是绑定到派生类的方法,造成了错误的行为。另外,我想移动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.

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

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