доступ к функции статического потока в нестатическом члене класса в C ++ - PullRequest
4 голосов
/ 08 января 2011
Class Test{
    int value;
    static void* thread_func(void* args){
        value++;
    }
    void newthread(){
        pthread_create(&thread_func,...);
    }
}

Я пытаюсь создать поток в Class Test. Поэтому компилятор заставляет меня сделать thread_func статическим.Однако я больше не могу получить доступ к нестатическому члену "value".Там написано:

invalid use of member 'Class::value' in static member function

Есть ли способ обойти это?

Ответы [ 2 ]

14 голосов
/ 08 января 2011

Однако я не могу получить доступ к нестатическому член "значение" больше.

Это потому, что функция static в вашем классе не имеет (а не может иметь) указатель this. Все, что вам нужно - передать указатель на ваш Test объект в функцию pthread_create () в качестве четвертого аргумента, а затем сделать это:

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

Однако, если в thread_func() вы делаете слишком много вещей, которые требуют доступа к Test ученикам во многих местах, то я бы предложил этот вариант:

//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
  }

Лучший дизайн: определите класс многократного использования!


Еще лучше было бы определить повторно используемый класс с pure виртуальной функцией run(), который будет реализован производными классами. Вот как это должно быть оформлено:

//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!
    }
}

выглядит лучше?

1 голос
/ 08 января 2011

Пусть thread_func принимает указатель на объект класса в качестве аргумента.

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

В случае, если этот метод также хочет получить некоторую другую информацию, поместите обе в другую struct/class и передайте этодюймы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...