I've been trying to understand operation overloading and the commutative property between classes and fundamental types. I declared the Test to Int asterisk operation but not the Int to Test, just to see if C++ would automatically provide with some sort of commutative function. The testing code is:
#include <iostream>
class Test{
public:
float x;
Test(){
x = 1;
}
Test(float number){
x = number;
}
~Test(){}
};
Test operator*(Test a, int b){
std::cout << "Alert! Test to Int happened! ";
return Test(a.x * b);
}
Test operator*(Test a, Test b){
std::cout << "Alert! Test to Test happened! ";
return Test(a.x * b.x);
}
int main(){
Test my_test;
std::cout << "First result: " << (my_test * 2).x << std::endl;
std::cout << "Second result: " << (3 * my_test).x << std::endl;
return 0;
}
with output:
First result: Alert! Test to Int happened! 2
Second result: Alert! Test to Test happened! 3
The first result was as expected, but for the second result I expected either an error or some unknown-to-me function to do the work. Instead, the Test to Test operation was used... Can someone explain why and what happened?
Your constructor with the form of
Test(float number){
x = number;
}
is what is called a converting constructor. Since it is not explicit, it allows you convert a float to a Test implicitly. You see that in
(3 * my_test).x
Here the 3 gets converted to a float in the standard conversion sequence and then that float get converted via the Test(float number) constructor. This then allows operator*(Test a, Test b) to be used.
To stop this, you make the constructor explicit like
explicit Test(float number){
x = number;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With