Ja, das stimmt. An den Thread übergibst du einen Zeiger auf die Funktion trampoline und einen Zeiger auf das Objekt myclass (in Form eines Zeigers auf void, weil C-Schnittstelle, statt C++-Schnittstelle). Der Thread ruft intern die übergebene Funktion mit dem übergebenen Argument auf, hier also die Funktion trampoline mit einem Zeiger auf das Objekt myclass (in Form eines Zeigers auf void, weil C-Schnittstelle, statt C++-Schnittstelle). Da man hier weiß, dass dieser void-Zeiger, p, auf ein Objekt der Klasse MyClass zeigt (man hat es ja selber so programmiert), kann man diesen void-Zeiger auch gefahrlos wieder zurück casten in einen Zeiger auf ein Objekt der Klasse MyClass . Und diesen kann man dann dereferenzieren und beispielsweise die Memberfunktion foo aufrufen. Da der void-Zeiger auf das Objekt myclass zeigte, wird also effektiv myclass.foo() aufgerufen.
Klingt komplizierter als es eigentlich ist.
Ich möchte noch einmal erwähnen, dass es in C++ auch ganz nativ Threads gibt. Mit einem richtigen C++-Interface, an das man direkt Funktionen und Objekte übergeben kann. Oder es gibt auch 3rd-Party Bibliotheken, die dies leisten, beispielsweise Boost::Thread (die eine große Inspiration für das Design der in C++ eingebauten Threads war). Oder man kann sich, wenn es unbedingt sein muss, selber Schnittstellen dieser Art bauen (Boost kocht schließlich auch nur mit Wasser), anstatt sich selber einen schlechten* Wrapper im C-Stil zu schreiben.
*: Ja, der hier gezeigte Wrapper ist schlecht. Was soll es bringen, eine Thread-Klasse zu erstellen, wenn man nicht einmal die Vorteile von Klassen benutzt? So wie es derzeit ist stellt die Klasse effektiv nur Aliase für die C-Threadfunktionen zur Verfügung, ohne jedwede Programmlogik (was man doch eigentlich erreichen möchte).