Reputation: 13
I have a class object with the following default constructor:
Point( double x = 0, double y = 0 );
If I create:
Point myPoint();
I'll get a point with (0, 0)
. If I create:
Point mySecondPoint(14);
I'll get a point with (14, 0)
.
But why is:
Point myThirdPoint(, 10) //invalid
not giving me a point of (0, 10)
. How should I code for a possibility of having the 2nd parameter, but not the first?
Upvotes: 1
Views: 260
Reputation: 30489
Unlike a few other languages, C++
mandates to supply all default arguments prior to the supplied arguments.
From 8.3.6 Default arguments [dcl.fct.default]
If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument. Default arguments will be used in calls where trailing arguments are missing.
So if a function has 5 arguments out of which 3 are default:
How should I code for a possibility of having the 2nd parameter, but not the first?
In my views your constructor interfaces are not very good. In this case I would prefer only two constructors, default without any argument and one with two arguments. If you want to give just one argument, you must specify the default of other by yourself.
i.e.
Point();
Point(double x, double y);
Or you should use some function to create a new Point
Point CreateWithY(double y)
{
return Point(0.0, y);
}
and use it as
Point p = CreateWithY(42.0); // Creates (0.0, 42.0)
Not part of the answer but:
Point myPoint();
declares a function myPoint which accepts no parameters and return an object of type Point
. What you intend to use is possibly:
Point myPoint;
Upvotes: 1
Reputation: 9602
Point myThirdPoint(, 10) //invalid
As others have stated this syntax is not supported by C++.
How should I code for a possibility of having the 2nd parameter, but not the first?
First you should consider if this is really what should be done. I don't know if there are more elegant ways to achieve this but you could introduce new types and rely upon overloading. Caveat, I'm not suggesting you should actually go this route rather just showing for illustration.
struct X
{
X(double v = 0.0) : mValue(v) {}
operator double() const { return mValue; }
private:
double mValue;
};
struct Y
{
Y(double v = 0.0) : mValue(v) {}
operator double() const { return mValue; }
private:
double mValue;
};
class Point
{
public:
Point() : mX(0.0), mY(0.0) {}
Point(X x) : mX(x), mY(0.0) {}
Point(Y y) : mX(0.0), mY(y) {}
Point(X x, Y y) : mX(x), mY(y) {}
private:
double mX;
double mY;
};
int main()
{
Point p1;
Point p2(X(1));
Point p3(Y(2));
Point p4(X(3), Y(4));
return 0;
}
Upvotes: 0
Reputation: 56557
Because C++ has some strict syntactic rules. Your example is simply incorrect from this point of view. When declaring default parameters, follow this rule: the default parameters that you'd want to change least frequently should be the rightmost default parameters, since C++ mandates specifying all parameters prior to the one you want to change its value from default.
Upvotes: 0