使用默认参数重载构造函数

时间:2014-01-25 00:57:27

标签: c++ class constructor

我有一个包含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个,那么在某些时候它必须“跳过”一个参数。例如,如果我只使用了第一个字符串,并且用户没有第二个字符串,那么就没有办法通过它来传递第二个字符串。

2 个答案:

答案 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'