Lessons learned
I am busy submitting versions before Christmas, and the encoding volume is greatly increased, with an average of 2,300 lines, sometimes thousands of lines. Code directly without design. Because it is related to some devices, output is the performance of the devices and there is no way to perform unit tests. In the process of doing so, I found a problem where the device crashed. Later I found out the cause, which was caused by misuse of the thread. I thought about it and wrote a blog to identify it.
Problematic Design
The design is very simple. There are four classes, one abstract class, two specific equipment classes and one factory class.
The client generates a pointer to a specific device class through the factory class and saves it to the pointer declared in the abstract class. Call methods of specific device classes through polymorphism.
Because scheduled tasks are required for both device classes, I generate a working thread in the abstract class and regularly call the multi-state method of subclass (specific device class) to execute the task. OnGenerate a thread in the constructor of the abstract class and send a signal in the interpretation function to exit the thread.The problem lies in the interpretation, because the interpretation of the abstract class is later than that of the specific equipment class, in the subclass (specific equipment class) the release function has been called (I deleted the pointer to the specific device operation in the release function of the subclass), but the working thread has not stopped, you may still be calling the multi-state method of the subclass to execute the task,ProgramIt may end up.
Solution
Create two protected methods. One is used to start the working thread, and the other is used to stop the working thread. The subclass stops the working thread before deleting the external device pointer. Everything runs normally.
Composition over inheritance
In fact, a better way is to decouple thread processing from this class structure. Instead of using multi-threaded processing through inheritance, the thread processing class is converted into a member of a subclass, the subclass controls when multithreading is used.
Continue to think.