C++
Putting it together
Combine all layers into a working mini framework.
Putting it together
In the final lesson we combine all layers: the skeleton, modern C++ data processing, the concurrency parallel sum, and the design pattern tasks. We now have a working mini framework.
All the code from previous lessons is in place: the Framework class, process_data, parallel_sum, Logger, TaskFactory. In this lesson we add an integration message at the end of the run method. This message confirms that all layers ran successfully. The output grows as the accumulation of four lessons: the ready message, the sum, the parallel sum, the log, and the integration message.
Final integration message
At the end of the run method, we will print a message confirming that all layers ran. This message comes after the execute() call.
Example: std::cout << std::endl << "run complete";. This line writes the integration message on a new line below the previous [log] output. This way the output shows the accumulation of four lessons: "Project ready", "sum: 4", "parallel: 4", "[log] task done" and "run complete". The framework is now fully working with all layers.
Exercise Add the final integration message
In the run method, after the t->execute(); line, add std::cout << std::endl << "run complete";. Do not touch the other code.
Show example solution
#include <iostream>
#include <string>
#include <vector>
#include <ranges>
#include <algorithm>
#include <concepts>
#include <thread>
#include <atomic>
#include <memory>
class Logger {
public:
static Logger& instance() {
static Logger inst;
return inst;
}
void log(const std::string& msg) { std::cout << "[log] " << msg; }
private:
Logger() = default;
};
class Task {
public:
virtual ~Task() = default;
virtual void execute() = 0;
};
class PrintTask : public Task {
public:
PrintTask(const std::string& m) : msg_(m) {}
void execute() override { Logger::instance().log(msg_); }
private:
std::string msg_;
};
class TaskFactory {
public:
static std::unique_ptr<Task> makePrint(const std::string& m) {
return std::make_unique<PrintTask>(m);
}
};
class Framework {
public:
int run();
template<std::integral T>
int process_data(const std::vector<T>& data);
int parallel_sum(const std::vector<int>& data);
};
template<std::integral T>
int Framework::process_data(const std::vector<T>& data) {
int sum = 0;
for (auto x : data | std::views::filter([](T v) { return v > 0; })) {
sum += x;
}
return sum;
}
int Framework::parallel_sum(const std::vector<int>& data) {
std::atomic<int> total{0};
std::thread t1([&]() { for (auto x : data) if (x > 0) total += x; });
t1.join();
return total;
}
int Framework::run() {
std::cout << "Project ready" << std::endl;
std::vector<int> data{1, -2, 3};
std::cout << "sum: " << process_data(data) << std::endl;
std::cout << "parallel: " << parallel_sum(data) << std::endl;
auto t = TaskFactory::makePrint("task done");
t->execute();
std::cout << std::endl << "run complete";
return 0;
}
int main() {
Framework fw;
fw.run();
return 0;
}
Test yourself
-
the run call
Framework fw; fw.____();
Show answer
Framework fw; fw.run();
-
What does integration mean?
- Deleting code
- Adding a new class
- Running all layers together to get an integrated application
- Skipping compilation
Show answer
Running all layers together to get an integrated application — Integration means running all layers together to get an integrated application.
-
Match each layer to its role
- process_data
- Data processing
- parallel_sum
- Parallel sum
- Logger
- Logging
- main()
- Integrated entry
Next lesson: Advanced section exam