Created
March 25, 2015 17:20
-
-
Save sansuiso/f764aff7bb176e739ce3 to your computer and use it in GitHub Desktop.
Concurrency bug (and solution)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <memory> | |
#include <thread> | |
class Base | |
{ | |
public: | |
/** | |
* Public interface to a complex algorithm. | |
* | |
* The complex algorithm can have variants (e.g., | |
* put the data in the correct shape, apply some | |
* post-processing to remove outliers in the result...). | |
* The virtual methdos are private so that clients of the class | |
* do only see a stable interface and the sequence of execution | |
* does also remain stable. | |
* | |
* The outline of the algorithm is always: | |
* 1. pre-processing step (can be overriden) | |
* 2. processing (fixed) | |
* 3. result post-processing (can be overriden) | |
*/ | |
void performComplexAlgorithm() const | |
{ | |
preprocessing(); | |
processing(); | |
postprocessing(); | |
} | |
private: | |
/** | |
* Prepare the data (e.g., convert RGB images to GRAY). | |
* Can be overriden by subclasses. | |
*/ | |
virtual void preprocessing() const | |
{ | |
std::cout << "Base::" << __FUNCTION__ << std::endl; | |
} | |
/** | |
* Really solve the problem here. | |
*/ | |
void processing() const | |
{ | |
std::cout << "Base::" << __FUNCTION__ << std::endl; | |
} | |
/** | |
* Post-process the data (remove outliers, put back to RGB...). | |
* Can be overriden by subclasses. | |
*/ | |
virtual void postprocessing() const | |
{ | |
std::cout << "Base::" << __FUNCTION__ << std::endl; | |
} | |
}; | |
/** | |
* Specialized class to deal with a certain type of data | |
*/ | |
class Derived : public Base | |
{ | |
private: | |
/** | |
* This special type of data needs to be put into a usable shape | |
* for our brilliant processing function. | |
*/ | |
virtual void preprocessing() const override | |
{ | |
std::cout << "Derived::" << __FUNCTION__ << std::endl; | |
} | |
}; | |
void wrongWorker(Base const solver) | |
{ | |
std::cout << "Inside " << __FUNCTION__ << std::endl; | |
solver.performComplexAlgorithm(); | |
} | |
void correctWorker(Base const& solver) | |
{ | |
std::cout << "Inside " << __FUNCTION__ << std::endl; | |
solver.performComplexAlgorithm(); | |
} | |
int main() | |
{ | |
std::cout << "Sanity check: call performComplexAlgorithm from Derived:" << std::endl; | |
Derived D0; | |
D0.performComplexAlgorithm(); | |
std::cout << std::endl; | |
std::unique_ptr<Base> D1 = std::unique_ptr<Derived>(new Derived); | |
std::cout << "Polymorphic access via a pointer:" << std::endl; | |
D1->performComplexAlgorithm(); | |
std::cout << std::endl; | |
std::cout << "Wrong (calls methods from the BASE class):" << std::endl; | |
wrongWorker(*D1); | |
std::cout << std::endl; | |
std::cout << "Correct (calls methods from the DERIVED class):" << std::endl; | |
correctWorker(*D1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment