Why is this conversion happening?
#include<iostream>
using namespace std;
class test
{
int a, b;
public开发者_Go百科:
test() {
a=4; b=5;
}
test(int i,int j=0) {
a=i; b=j;
}
test operator +(test c) {
test temp;
temp.a=a+c.a;
temp.b=b+c.b;
return temp;
}
void print() {
cout << a << b;
}
};
int main() {
test t1, t2(2,3), t3;
t3 = t1+2;
t3.print();
return 0;
}
How can the compiler accept a statement like t3=t1+2;
where 2
is not an object?
The compiler sees you are invoking operator+(test)
and attempts to implicitly convert the 2
to a test
successfully using your test(int i,int j=0)
constructor.
If you want to make the conversion explicit, you must change the constructor to explicit test(int i, int j=0)
. In this case, your code would generate a compiler error because 2
cannot be implicitly converted to test
. You would need to change the expression to t1 + test(2)
.
Because test(int i,int j=0)
is a constructor that takes one or two arguments, so a test
object is created from 2
. In the next stage test operator +(test c)
is called.
There is a binary operator+
available which takes two operands of type test
. Moreover, test
is implicitly constructible from int
via the constructor test(int, int = 0)
. Putting the two together, t1 + 2
becomes t1 + test(2, 0)
.
To disallow this silent conversion (which sometimes can cause very surprising conversion chains), declare your constructors that accept one single argument as explicit: explicit test(int, int = 0)
.
Because test(int i, int j = 0)
is not marked explicit.
Therefore t1 + 2
is interpreted as t1.operator+(2)
which is itself interpreted as t1.operator+(test(2))
(implicit conversion).
If you mark the constructor as explicit
, an error will occur (during the compilation), saying that 2
cannot be converted into a test
or that the operator+
does not match.
In short, because C++ includes operator overloading, the ability to define custom implementations of operators for user-defined types. The operator+()
function shown above is how you define the +
operator for the type test
. When the compiler sees an expression in which +
is applied to a test
object, it looks for an operator+
defined in test
(or a two-argument form defined as a global function with a first argument of type test
or test&
.) It then invokes the function, possibly after converting the other argument.
Because your constructor test(int i,int j=0)
introduces a user defined conversion from int
to test
.
The compiler creates an object of type Test using its constructor.
t3 = t1 + test(2);
精彩评论