我赞成@πάντα ῥεῖ(你怎么写!?)的想法。
首先,我们有 abstract_sink 一个结构,它将充当我们所有接收器的接口。
struct abstract_sink {
virtual void on_progress_inc(int progress) = 0;
};
两个示例接收器:
struct my_sink : abstract_sink {
void on_progress_inc(int progress) {
std::cout << "The progress: " << progress << "%" << std::endl;
}
};
struct my_another_sink : abstract_sink {
void on_progress_inc(int progress) {
std::cout << "The progress: " << progress << " --- " << std::endl;
}
};
最后会实现一个仿函数(参见:C++ Functors - and their uses),这个仿函数代替你的成员函数。
template<typename Sink>
struct process_file_functor
{
// Constructor.
process_file_functor(Sink &sink)
{
m_sink = std::make_shared<Sink>(sink);
}
void operator()(std::string infile, std::string outfile)
{
std::fstream inf(infile);
std::fstream out(outfile);
int total_lines = std::count(std::istreambuf_iterator<char>(inf), std::istreambuf_iterator<char>(), '\n');
inf.seekg(0);
int progress = 0;
for (std::string line; std::getline(inf, line); )
{
/*
Here you will do what you have to do and in every iteration
you will compute progress = 100 * lines_processed / total_lines and call...
*/
progress++;
m_sink->on_progress_inc(100 * progress/total_lines); // Here you notify the progress.
}
}
std::shared_ptr<Sink> m_sink;
};
使用示例:
#include <iostream>
#include <fstream>
#include <memory>
#include <string>
#include <thread>
int main(int argc, char *argv[])
{
my_sink ms;
my_another_sink mas;
process_file_functor<my_sink> pfile(ms);
process_file_functor<my_another_sink> pfile1(mas);
std::thread t1(pfile, "data1.txt", "data2.txt");
std::thread t2(pfile1, "data1.txt", "data2.txt");
t1.join();
t2.join();
return 0;
}
重要提示:此代码不处理并发,不要将其用于生产只是说明性的。