Reputation: 199
I am reviewing for my final, and I cannot figure out why this question is what it is.
Assume the following class declaration:
class Testing {
public:
Testing(int n);
void Show(const Testing& w, int a = 10);
int value;
private:
int DoThis();
};
Assume the following lines of code are attempting in a main() program, and that x is of type Testing
and has been propertly created.
x.Show(18);
Legal or Illegal
The answer is legal, I understand that the 2nd parameter is not needed because of the = 10
,but since 18
is not of type Testing
isn't that an invalid parameter?
Upvotes: 6
Views: 258
Reputation: 36852
Testing has a non-explicit
constructor that takes an int. Therefore, an int can be implicitely converted to a Testing
by constructing a temporary object.
Since Show takes a const Testing &
(and not just a Testing &
), you can pass a temporary to it. Finally, the second parameter is optional, so you don't have to specify a value for that.
This whole mechanism is what allows you do this, by the way:
void f(const std::string &str);
// ...
f("Hello");
Here, "Hello"
is of type const char (&)[6]
, which decays to a const char *
, but you can construct a std::string
from a const char *
, thus permitting the use of a const char *
where a std::string
parameter is needed.
Keep in mind that this constructs a temporary, and therefore is only valid for parameters that are passed by value or by const reference (it will fail for references). Also, the constructor must not be marked as explicit
.
Upvotes: 16
Reputation: 127447
There is a notion of automatic conversions in C++, called implicit conversion sequences. At most one conversion in such a sequence may be a user defined one, and calling a constructor for a temporary object is a user-defined conversion. It's ok to create a temporary here as that will be bound to the const-reference, and destroyed when the Show() call is complete.
Upvotes: 6
Reputation: 44256
Because Testing
has a constructor that accepts an int
, that c-tor is used to automatically construct a Testing
object for the first parameter. The code actually ends up working something like:
x.Show(Testing(18));
Upvotes: 5
Reputation: 54128
The constructor here:
Testing(int n);
provides an implicit conversion from int
to Testing
, and this then matches the prototype for Show
, with the first parameter being a Testing
instance constructed from the int
18, and the second parameter being the default value 10.
If you prevent implicit conversion like this:
explicit Testing(int n);
the code will not compile.
Upvotes: 3