0

I have a class with 5 variables: 2 strings, 2 doubles, and one int.

The user will always be able to provide at least one string and one double, but may not be able to supply the rest of the information, meaning default arguments should be included.

Of course, trying to create a bunch of constructors with all the arguments does not work - it fails to compile.

Say I try something like this instead:

         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...

This would be overloading the constructor, but are these still considered default arguments?

Is there a way to include every parameter in every constructor with default arguments? i.e., similar to this type of thing that doesn't work:

 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...

The problem with this is that if the user only has 4 of the 5 values needed, at some point it would have to "skip" a parameter. For example, if I just used the first one, and the user didn't have the second string, there wouldn't be a way to go past it to pass the second double.

3
  • 6
    What's wrong with just having the first signature in your last example? Commented Jan 25, 2014 at 0:58
  • What error are you getting? What you're trying to do in your second example should work. Commented Jan 25, 2014 at 1:04
  • Exactly. That's all you need. You're over-thinking this. Commented Jan 25, 2014 at 1:04

2 Answers 2

1

For classes with that many construction parameters, I'd suggest you use the builder pattern. This pattern basically uses a separate builder class that holds all the construction parameters, which are then all passed to your real class's constructor.

Using the builder pattern, you can establish the default parameter values inside your builder, so your calling code can still stay simple if it only needs to override one or two parameters.

(If you used real class and parameter names in your question, I could have written a sample builder to demonstrate the point, but hopefully reading about the builder pattern would give you an idea to work with.)

Sign up to request clarification or add additional context in comments.

Comments

1

Default argument values are specified in the parameter list (not the function body), as you show in the 2nd code sample.

All you need in the body is

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;
}

Although, the proper C++ syntax is to use an initializer list:

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
}

When a user calls the constructor with s1 and d1, or optionally i, s2, and d2 specified, the default values will be filled in. The only caveat is they have to be supplied in that order. You can't supply just i and d2, you can only suply i and s2, or i, s2 and 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'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.