基本的想法是,我有一个类的“家庭”,它们都做同样的事情,但方式略有不同。这个“家庭”用于“高性能”循环,因此速度至关重要。此外,特定系列由配置文件...
指定问题是这里的主要功能中存在巨大的代码重复。有没有更好的方法来构建这个,所以我不必写三次HP<objx> test
和test.loop(bobloblaw)
? (实际上,这段代码的行多于2行......)
class obj1 {
public:
double f(double x) const { return 1.; }
};
class obj2 {
public:
double f(double x) const { return x; }
};
class obj3 {
public:
double f(double x) const { return x*x; }
};
template <class O>
class HP {
private:
O obj;
public:
double loop(const vector<double>& x) {
double s = 0.;
for (auto i : x) s += obj.f(i);
return s;
}
};
int main() {
string config = "bob";
double result = 0;
vector<double> bobloblaw;
/* Read configuration file to determine which object to use. */
if (config == "obj1") {
HP<obj1> test;
result = test.loop(bobloblaw);
} else if (config == "obj2") {
HP<obj2> test;
result = test.loop(bobloblaw);
} else if (config == "obj3") {
HP<obj3> test;
result = test.loop(bobloblaw);
}
return result;
}
答案 0 :(得分:4)
以下是未经测试的,但应该有效:
class obj1
{
public:
double f(double x) const { return 1.; }
};
class obj2
{
public:
double f(double x) const { return x; }
};
class obj3
{
public:
double f(double x) const { return x*x; }
};
class HPbase
{
public:
virtual double loop(const vector<double>&) = 0;
};
template <class O> class HP:
public HPbase
{
public:
double loop(const vector<double>& x)
{
double s = 0.;
for (auto i : x)
s += obj.f(i);
return s;
}
private:
O obj;
};
std::unordered_map<std::string, std::unique_ptr<HPbase>> decode{
{"obj1"}, new HP<obj1>()},
{"obj2"}, new HP<obj2>()},
{"obj3"}, new HP<obj3>()} };
int main()
{
string config = "bob";
double result = 0;
vector<double> bobloblaw;
/* Read configuration file to determine which object to use. */
result = decode[config].loop(bobloblaw);
}
请注意,唯一添加的是HP<>
的基类和替换代码的if
/ else
逻辑的地图。
答案 1 :(得分:3)
难道你不能让这3个类都是同一个父类的子类吗? main仍然需要使用正确的子类分配给测试,但测试本身将被声明为常见的超类。
这里的缺点是可能存在(可能很小的)性能损失,因为编译器不知道何时为test.loop生成将使用哪个版本的代码,因此必须在运行时决定。
另一种可以解决这个问题的方法是将公共代码编写为宏,因此只能编写一次但扩展为3个不同的副本,编译器可以根据测试的变体优化每个副本正在使用。可以使调试成为一个婊子,但如果你的重点是性能和减少源的冗余(而不是对象的冗余),这可能是一个很好的权衡。