int main() {
int theInt = 5;
/**
* Constructor "Example(int val)" in effect at the statement below.
* Same as "Example exObject(theInt);" or "Example exObject = Example(theInt);"
*/
Example exObject = theInt; // 1
Example ctr(5);
/**
* "operator unsigned int()" in effect at the statement below.
* What gets assigned is the value returned by "operator unsigned int()".
*/
int theInt1 = ctr; // 2
return 0;
}
At statement 1 the constructor Example(int val)
is called. Declare it as explicit Example(int val)
and you will get a compile time error i.e. no implicit conversion will then be allowed for this constructor.
All single argument constructors are called implicitly if the assigned value is of their respective argument type. Using the explicit
keyword before single argument constructors disables implicit constructor calling and hence implicit conversion.
If the constructor was declared as explicit i.e. explicit Example(int val)
then the following would happen for each statement.
Example exObject(theInt); // Compile time error.
Example exObject = theInt; // Compile time error.
Example exObject(Example(theInt)); // Okay!
Example exObject = Example(theInt); // Okay!
Also note that in case of implicit constructor call and hence implicit conversion the assigned value is an rvalue i.e. an un-named object implicitly created using an lvalue (theInt) which tells us that in case of implicit conversion the compiler converts
Example exObject = theInt;
to
Example exObject = Example(theInt);
So (in C++11) don't expect the lvalue constructor to be called seeing that you are using an lvalue i.e. a named value theInt
for assignment. What gets called is the rvalue constructor since the assigned value is actually the un-named object created using the lvalue. However, this applies if you have both lvalue and rvalue versions of the constructor.
At statement 2 operator unsigned int()
is called. Simply consider it as a normal function call with a weird name and the fact that it can get called automagically when an implicit conversion happens. The value returned by that function is the value assigned in the expression. And since in you implementation the value returned is an int it correctly gets assigned to int theInt1
.
To be precise operator unsigned int()
overloads ()
operator which is the cast operator. In your case it's overloaded for int
hence whenever an object of Example
class is assigned to an int
the implicit type casting from Example
to int
takes place and hence operator unsigned int()
gets called. Therefore,
int theInt1 = ctr;
is equivalent to
int theInt1 = (int)ctr;