Hacker News new | ask | show | jobs
by servaldeneptuno 910 days ago
I have an unrelated (and most likely dumb) question about the article. When they talk about the inheritance relationship between 'Thread' and 'MyThread' in the example code in reference to the destructor methods, particularly here:

> Now, what happens when MyThread::singlepassThreadWork() uses a member variable of MyThread like foobar and we delete the MyThread object while the thread is still running? The destruction sequence is such that MyThread is deleted first and after that, the destructor of its parent object Thread runs and the thread is joined. Thus, there is a race condition: We risk accessing the vector foobar in singlepassThreadWork() after it was already deleted. We can fix the user code by explicitly stopping the thread in its destructor

What does it mean when they say 'the destructor of its *parent* object Thread runs'? I've always thought that when you inherit from one class to another and then instantiate an object of said class, they're just one object, so what do they mean when they make the distinction between 'parent' and 'child' object? When you have inheritance of say two classes, those would be two distinct objects instantiated in memory? Is there something I'm missing?

2 comments

You're right, the wording is confusing. It should be "parent class". There is only one object, a MyThread object. In C++ when an object is destroyed, all the destructors in the hiearchy run, from bottom to top. So first ~MyThread and then ~Thread.

Anyway I think it is odd design to stop the thread in the destructor. You'd normally stop the thread first and then destroy the object, not the other way around?

They might be trying to encapsulate things so that they are sure threads get stopped when the objects go out of scope.

But, I would probably do that by having a class that contains both the thread and the data that the thread needs to access. Then its destructor could first join the thread and then clean up the data. For example, instead of a WorkerThread that contains a vector of WorkItem, have a BackgroundWorker that contains a Thread and a vector of WorkItem.

I see now, thank you very much
https://en.cppreference.com/w/cpp/language/destructor

Take a look at "Destruction sequence" but basically the destructors are chained together and called one after another to free all resources rather than forming one destructor for the derived object. That being said it is still effectively one object in memory.

Thank you for the explanation and reference.