[C++] Wątek na metodzie NIE-statycznej

Witam!

Potrzebuję utworzyć nowy wątek w swojej metodzie. wydawało by się, nic trudnego, ale jako procedurę obsługi wątku muszę użyć metody nie statycznej.

używam CreateThread , projekt się kompiluje, ale procedura obsługi wątku wykonuje się do momentu użycia pierwszego niestatycznego atrybutu.

Czy istnieje sposób, by na to zaradzić? może jakaś inna funkcja do tworzenia wątku?

To “wina” języka - C++ sam w sobie nie obsługuje tzw. delegatów. Ale da się to dość prosto obejść. Użyj metody statycznej, jako parametr wątku podaj wskaźnik na żądany obiekt i z poziomu tej metody wywołaj metodę obiektu.

class Thread

{

public: void Run() {/*...*/}

};


void ThreadMain(LPVOID param)

{

((Thread*)param)->Run();

}


//...

Thread th;

CreateThread(NULL, 0, ThreadMain, (LPVOID)&th, 0, NULL);

sprytne:D

dzięki;)

Tylko bądź świadom tego, że zaproponowany cast przestanie działać jeśli użyjesz bardziej złożonego dziedziczenia i znaczenie zacznie mieć budowa vtable. Generalnie jedyną uniwersalną odpowiedzią na Twój problem jest: nie rób tego. Nie rób i tyle.

class Thread

  {

   public: 

   void Run() {/*...*/}

   void Start() { CreateThread(0,0,SRun,reinterpret_cast<(LPVOID)>this,0,0);

   private:

   static void SRun(LPVOID param) { reinterpret_cast(param)->Run(); }

  };

I masz w nosie vtable.

Mógłbyś rozwinąć, jak na to wpływa vtable? Czy może masz na myśli wielodziedziczenie?

@[alex]: AFAICR reinterpreted_cast działa identycznie jak rzutowanie C-style, tylko trzeba się więcej napisać.

EDIT:

@down: dzięki za wyjaśnienie.

To jest praktycznie to samo. A nie należy używać z powodów opisanych w części 33. C++ FAQ, sugeruję przeczytać. Jest tam też obejście dla wywołań, które oczekują callbacka i dają opcjonalny parametr. Krótka odpowiedź dla niecierpliwych to: standard określa takie wywołanie jako undefined, co znaczy, że do twórców kompilatora należy ustalenie czy działa, jak i kiedy. Mogą to implementować jak chcą i robią tak. I mogą działanie podobnego casta zmienić kiedy chcą, w końcu zachowanie nie jest częścią standardu. Szczególnie zachowanie przestaje być przewidywalne, gdy funkcja jest wirtualna. Albo miała słowo kluczowe virtual w klasie bazowej a w potomnej już nie. Czasem przy większej złożoności kodu nie uzyskujemy oczekiwanego rezultatu, czasem całkiem szybko. Jest jeszcze kilka pobocznych powodów. Nie należy tak robić i już.

Nie myl powinno działać identycznie z działa identycznie.

Pamiętam 3 dni debugowania kodu kiedy to rzutowanie c-style na void* zmieniało mi wskaźnik na klasę bazową, więc po powrotnym rzutowaniu program zaczynał się sypać.

Zgłosiłeś błąd w kompilatorze?