c ++,pthread和静态回调。 “这个”返回指向派生类的基类的指针 [英] c++ , pthread and static callbacks. "this" returns a pointer to the base class inctead of the derived one

查看:104
本文介绍了c ++,pthread和静态回调。 “这个”返回指向派生类的基类的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用这个 cpp线程类作为基础。这我用作线程的基类。注意,在我的情况下Thread :: main()是一个虚函数(不像在链接)。所以我基本上使用:

I am using as basis this cpp thread class. This I use as a base class for threads. Note that in my case Thread::main() is a virtual function (unlike in the link). So I basically use:

class Thread {
public:
    virtual void main()
    {
        cout << "This should not be run once derived and redefined." << endl;
    }

    void run()
    {
        pthread_create(&thread, 0, &callback, this);
    }

    pthread_t thread;
}; // class Thread


void* callback(void* obj)
{
    static_cast<Thread*>(obj)->main();
    return(0);
} // callback

然后我创建一个派生类并重新定义<$

Then I create a derived class and re-define the myThreadedClass::main() member to actually do something meaningful.

最后,我从其他类实例化myThreadedClass对象,或者从其他类实例化myThreadedClass对象。我的主要函数调用如下:

Finally, I instantiate the myThreadedClass object from other classes or my main function call as follows:

main(int argc, char** argv){
    myThreadedClass thr;
    thr.run();

    //do other stuff
}

;回调函数获取一个指向派生类实例化的指针,所以执行 myThreadedClass :: main()

This works fine; The callback function gets a pointer to the derived class instantiation, so the myThreadedClass::main() gets executed.

然而,我现在尝试创建一个不同的派生类 class otherThreadClass:public Thread 。再次重新定义我的 otherThreadClass :: main(),但现在我有一个成员函数在派生类中(不像以前)调用Thread :: run()。

However, I now try to create a different derived class class otherThreadClass : public Thread. Again I re-define my otherThreadClass::main() , but now I have a member function in the derived class which (unlike before) calls Thread::run().

class otherThreadClass : public Thread{
public:
    writeToDiskAsync(string& str){
       prepareString(str);

       //spawn a thread to carry the write without blocking execution
       run();
    }
};

在这种情况下从我的主要功能I do

in this case from my main function I do

main(int argc, char** argv){
    otherThreadClass thr;
    thr.writeToDiskAsync(aString);

    //do other stuff
}

这种情况是回调函数获取一个指向Thread类的指针,而Thread :: main()最终被执行,而不是otherThreadClass :: main()。

The problem in this case is that the callback function gets a pointer to the Thread class and the Thread::main() ends up being executed instead of the otherThreadClass::main().

我尝试传递一个指针到实例化的myThreadedClass对象(使用初始化列表和改变的调用Thread :: run(void * instance))如下

I tried passing a pointer to the instantiated myThreadedClass object during instantiation (using initialisation lists and an altered call to Thread::run(void* instance)) as follows

//in main function
otherThreadClass thr(&thr);

//in class
otherThreadClass::otherThreadClass(otherThreadClass* ptr):instancePtr(ptr)
{}

otherThreadClass::writeToDiskAsync(string& str)
{
    //do stuff
    run(instancePtr);
}

//and finally

Thread::run(void* parentObj)
{
    pthread_create(&thread, 0, &callback, parentObj);
}

但不起作用。我认为这可能不是一个很好的方式来做它反正。那么我能做什么让回调函数获取apointer到派生类实例而不是基类?

but it does not work. And I think this is probably not a nice way to do it anyway. So what can I do to let the callback function get apointer to the derived class instance instead of the base class ?

谢谢

推荐答案

如果你将尝试使用基类ptr调用一个函数,每次基类的版本被调用,只要函数不是虚拟的。
这样简单的解决你的问题将是使主虚拟如下:

If you will try to call a function using base class ptr , everytime base class version gets called as long as function is not virtual . so simpler solution to your problem would be to make main virtual as below :

  #include <iostream>
#include<pthread.h>
#include<unistd.h?
using namespace std;
void* callback(void* obj);
class Thread {
public:
  virtual  int main()
    {
        cout << "Hi there Base class" << endl;
        return(0);
    }

    void run()
    {
        pthread_create(&thread, 0, &callback, this);
    }

    pthread_t thread;
};

class otherThreadClass : public Thread{
public:
virtual  int main()
    {
        cout << "Hi there other class" << endl;
        return(0);
    }


   void writeToDiskAsync(string str){


       //spawn a thread to carry the write without blocking execution
       run();
    }
};

class Thread;
void* callback(void* obj)
{
    static_cast<Thread*>(obj)->main();
    return(0);
} // callback


int main() {
    // your code goes here
    otherThreadClass thr;
    thr.writeToDiskAsync(string("aS"));
sleep(10);//it is neccessary as main thread can exit before .
    return 0;
}
output : Hi there other class

,它将永远调用main的基类版本,因为你通过基类ptr(静态绑定将发生)调用

Whereas if main is not virtual , it will always call base class version of main as you are calling through a base class ptr (static binding will happen )

这篇关于c ++,pthread和静态回调。 “这个”返回指向派生类的基类的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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