static thread function access non-static class member in C++

前端 未结 2 846
时光说笑
时光说笑 2021-01-03 08:22
Class Test{
    int value;
    static void* thread_func(void* args){
        value++;
    }
    void newthread(){
        pthread_create(&thread_func,...);
    }         


        
相关标签:
2条回答
  • 2021-01-03 08:46

    Let thread_func take a pointer to an object of the class as argument.

    static void* thread_func(void* pThis)
    {
        static_cast<Test*>(pThis)->value++;
    }
    

    In case, this method wants to take some other information as well, put both in another struct/class and pass that in.

    0 讨论(0)
  • 2021-01-03 09:01

    However I cannot access the non-static member "value" anymore.

    That is because static function in your class doesn't have (and cannot have ) this pointer. All you need to pass the pointer to your Test object to pthread_create() function as fourth argument, and then do this:

    static void* thread_func(void* args)
    {
          Test *test = static_cast<Test*>(args);
          test->value++;
          //write return statement properly
    }
    

    However, if you're doing too many things in thread_func() that require access to Test class members at many places, then I would suggest this design:

    //this design simplifies the syntax to access the class members!
    class Test
    {
        //code omitted for brevity
    
        static void* thread_func(void* args)
        {
              Test *test = static_cast<Test*>(args);
              test->run(); //call the member function!
              //write return statement properly
        }
        void run() //define a member function to run the thread!
        { 
              value++;//now you can do this, because it is same as 'this->value++;
              //you do have 'this' pointer here, as usual; 
              //so access other members like 'value++'.
        }
        //code omitted for brevity
      }
    

    Better design : define a reusable class!


    Even better would be to define a reusable class with pure virtual function run() to be implemented by the derived classes. Here is how it should be designed:

    //runnable is reusable class. All thread classes must derive from it! 
    class runnable
    {
    public:
        virtual ~runnable() {}
        static void run_thread(void *args)
        {
            runnable *prunnable = static_cast<runnable*>(args);
            prunnable->run();
        }
    protected:
        virtual void run() = 0; //derived class must implement this!
    };
    
    class Test : public runnable //derived from runnable!
    {
    public:
        void newthread()
        {
            //note &runnable::run_thread
            pthread_create(&runnable::run_thread,..., this);
        }
    protected:
        void run() //implementing the virtual function!
        {
            value++; // your thread function!
        }
    }
    

    Looks better?

    0 讨论(0)
提交回复
热议问题