私は問題に直面した大きなプロジェクトを持っています。それはすぐに次のように定式化することができます:
一時的に作成され、一部のデータを処理および変更するために使用されるクラスがありました(これを「ワーカー」と呼びましょう)。これで、2つのワーカーと2つの対応するデータ形式ができました。データ配列には混合データを含めることができますが、プログラムで作成してデータ処理に使用するワーカークラスを自動的に決定するにはどうすればよいですか?これを最善の方法で作成するにはどうすればよいですか?
この問題を説明するために、私のプロジェクトに類似した小さなサンプルプログラムを作成しました。
#include <iostream>
#include <vector>
using namespace std;
const int NInputs = 10;
struct TOutput {
int i;
};
class TProcess {
public:
TProcess( const vector<TInput>& i ){ fInput = i; }
void Run();
void GetOutput( TOutput& o ) { o = fOutput; }
private:
vector<TInput> fInput;
TOutput fOutput;
};
#if 0
struct TInput {
int i;
};
class TWorker{
public:
void Init( int i ) { fResult = i; }
void Add( int i ) { fResult += i; }
int Result() { return fResult; }
private:
int fResult;
};
#else
struct TInput {
int i;
};
class TWorker {
public:
void Init( int i ) { fResult = i; }
void Add( int i ) { fResult ^= i; }
int Result() { return fResult; }
private:
int fResult;
};
#endif
void TProcess::Run() {
TWorker worker;
worker.Init(0);
for( int i = 0; i < fInput.size(); ++i )
worker.Add(fInput[i].i);
fOutput.i = worker.Result();
}
int main() {
vector<TInput> input(NInputs);
for ( int i = 0; i < NInputs; i++ ) {
input[i].i = i;
}
TProcess proc(input);
proc.Run();
TOutput output;
proc.GetOutput(output);
cout << output.i << endl;
}
例は非常に単純ですが、それはそれを1つの関数に変換することが単純に可能であることを意味するわけではありません---それは大きなプロジェクトに対応します。したがって、次のことはできません。
- すでに存在するクラスまたは関数を削除します(ただし、それらを変更して新しいものを作成することは可能です)
- ワーカーを静的にするか、ワーカーのコピーを1つだけ作成します(各ワーカーは、多くの複雑な関数やループで一時的なものです)
したがって、これが次のようになるように変更する方法は次のとおりです。
// TODO: TProcess declaration
struct TInput1 {
int i;
};
class TWorker1{
public:
void Init( TInput1 i ) { fResult = i; }
void Add( TInput1 i ) { fResult += i.i; }
int Result() { return fResult; }
private:
int fResult;
};
#else
struct TInput2 {
int i;
};
class TWorker2 {
public:
void Init( TInput2 i ) { fResult = i.i; }
void Add( TInput2 i ) { fResult ^= i.i; }
int Result() { return fResult; }
private:
int fResult;
};
void TProcess::Run() {
for( int i = 0; i < fInput.size(); ++i ) {
// TODO: choose and create a worker
worker.Add(fInput[i].i);
// TODO: get and save result
}
fOutput.i = worker.Result();
}
int main() {
vector<TInputBase> input(NInputs);
// TODO: fill input
TProcess proc(input);
proc.Run();
TOutput output;
proc.GetOutput(output);
cout << output.i << endl;
}
私の最初のアイデアは、基本的なクラス関数とテンプレート関数を使用することでしたが、テンプレート仮想関数はありません...