The first argument that you pass to the thread constructor is a function pointer.
In this case it's a pointer to a
member function so you also need to pass a pointer to the object that the function should be called on (it doesn't make sense to call a member function without an object) and that is why you pass
this (which is a pointer to the current object) as a second argument.
I cannot answer why you have to write exactly
&Data::read_data to get a pointer to the function. I guess they could have allowed
this->read_data (or perhaps
&this->read_data) but it wouldn't really add much because, no matter which Data object you used in that expression, you would always get the same function pointer.
Also, don't call the thread destructors explicitly. It will be called automatically when the thread object goes out of scope.
It is almost always wrong to call destructors explicitly. It's mainly used in combination with
placement new, which is something that most people never, or very rarely, use.