如果我有一个带有 2 个必需参数和 4 个可选参数的构造函数,我如何避免编写 16 个构造函数甚至 10 个左右的构造函数,如果我使用默认参数(我不喜欢它,因为它很差)自我证明)?是否有任何使用模板的习语或方法可以用来减少乏味?(并且更易于维护?)
问问题
1411 次
4 回答
34
您可能对Named Parameter Idiom感兴趣。
总而言之,创建一个包含要传递给构造函数的值的类。添加一个方法来设置每个值,并让每个方法return *this;
在最后执行一个。在你的类中有一个构造函数,它接受这个新类的 const 引用。这可以像这样使用:
class Person;
class PersonOptions
{
friend class Person;
string name_;
int age_;
char gender_;
public:
PersonOptions() :
age_(0),
gender_('U')
{}
PersonOptions& name(const string& n) { name_ = n; return *this; }
PersonOptions& age(int a) { age_ = a; return *this; }
PersonOptions& gender(char g) { gender_ = g; return *this; }
};
class Person
{
string name_;
int age_;
char gender_;
public:
Person(const PersonOptions& opts) :
name_(opts.name_),
age_(opts.age_),
gender_(opts.gender_)
{}
};
Person p = PersonOptions().name("George").age(57).gender('M');
于 2010-04-23T18:19:43.840 回答
9
如果您创建了一个包含所有字段的参数对象怎么办?然后你可以通过它,然后设置你需要的任何字段。该模式可能有一个名称,但不确定它是什么......
更新:
代码可能看起来像这样:
paramObj.x=1;
paramObj.y=2;
paramObj.z=3;
paramObj.magic=true;
... //set many other "parameters here"
someObject myObject = new someObject(paramObj);
在someObject
构造函数中,您可以为尚未设置的内容设置默认值(如果是强制性的,则引发错误)。
老实说,我不是这个解决方案的忠实拥护者,但我已经使用过一次或两次,因为它paramObj
包含一组通常都在一起的数据(所以我们可以将它用于不仅仅是构造函数),并且它比多个构造函数更好。我发现它很丑,但它有效,YMMV。
于 2010-04-23T18:20:11.810 回答
4
现在对于“Boost有一些东西”的答案:
Boost Parameter Library似乎非常适合您的用例。
于 2010-04-23T18:52:25.900 回答
2
C++17 的全新
#include <optional>
using optional_int = std::optional<int>;
class foo {
int arg0, arg1; // required
int arg2, arg3; // optional
const int default_2 = -2;
const int default_3 = -3;
public:
foo(int arg0, int arg1, optional_int opt0 = {}, optional_int opt1 = {})
: arg0(arg0), arg1(arg1)
, arg2(opt0.value_or(default_2))
, arg3(opt1.value_or(default_3))
{ }
};
int main() {
foo bar(42, 43, {}, 45); // Take default for opt0 (arg2)
return 0;
}
我有一个三次样条实现,它允许用户选择在左端、右端或两者都指定一阶导数。如果未指定导数,则代码实际上计算一,假设二阶导数为零(所谓的“自然样条”)。这是左端的片段。
// Calculate the second derivative at the left end point
if (!left_deriv.has_value()) {
ddy[0]=u[0]=0.0; // "Natural spline"
} else {
const real yP0 = left_deriv.value();
ddy[0] = -0.5;
u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yP0);
}
于 2018-01-20T06:01:42.117 回答