我有一个包含5个变量的类:2个字符串,2个双精度数和1个int。
用户将始终能够提供至少一个字符串和一个double,但可能无法提供其余信息,这意味着应包含默认参数。
当然,尝试使用所有参数创建一堆构造函数不起作用 - 它无法编译。
说我尝试这样的事情:
Object(std::string s1, double d1) {
this->string1 = s1;
this->double1 = d1;
this->int1 = 0;
this->double2 = 0.0;
this->string2 = "foo";
}
Object(std::string s1, double d1, int i) {
this->string1 = s1;
this->double1 = d1;
this->int1 = i;
this->double2 = 0.0;
this->string2 = "foo";
}
// and so on...
这会重载构造函数,但这些仍然被认为是默认参数吗?
有没有办法在每个构造函数中包含默认参数的每个参数?即,类似于这种不起作用的东西:
Object(std::string s1, double d1, int i = 0, std::string s2 = "foo", double d2 = 0.0) {
...
}
Object(std::string s1, double d1, int i, std::string s2 = "foo", double d2 = 0.0) {
...
}
// and so on...
这个问题是如果用户只需要5个值中的4个,那么在某些时候它必须“跳过”一个参数。例如,如果我只使用了第一个字符串,并且用户没有第二个字符串,那么就没有办法通过它来传递第二个字符串。
答案 0 :(得分:1)
对于具有许多构造参数的类,我建议您使用builder pattern。这个模式基本上使用一个单独的构建器类来保存所有构造参数,然后将它们全部传递给真实类的构造函数。
使用构建器模式,您可以在构建器中建立默认参数值,因此如果只需要覆盖一个或两个参数,您的调用代码仍然可以保持简单。
(如果您在问题中使用了真实的类和参数名称,我可以编写一个示例构建器来演示这一点,但希望阅读构建器模式会让您有一个想法可以使用。)
答案 1 :(得分:1)
默认参数值在参数列表(不是函数体)中指定,如第二个代码示例中所示。
身体所需要的只是
Object(std::string s1, double d1, int i = 0, std::string s2 = "foo", double d2 = 0.0)
{
this->string1 = s1;
this->double1 = d1;
this->int1 = i;
this->double2 = s2;
this->string2 = d2;
}
虽然,正确的C ++语法是使用初始化列表:
Object(std::string s1, double d1, int i = 0, std::string s2 = "foo", double d2 = 0.0):
string1( s1 ),
double1( d1 ),
int1( i ),
double2( s2 ),
string2( d2 )
{
// constructor body
}
当用户使用s1和d1或者指定的i,s2和d2调用构造函数时,将填充默认值。唯一需要注意的是它们必须按顺序提供。你不能只提供i和d2,你只能提供i和s2,或i,s2和d2。
Object myobject ( "s1", 0.5 ); //valid
Object myobject ( "s1", 0.5, 9, "foo" ); //valid
Object myobject ( "s1", 0.5, "s2" ); //invalid, skipped parameter 'i'