today my teacher showed me the following example:
CFraction operator*(const CFraction &a, const CFraction &b){
CFraction x;
x.setNumerator(a.getNumerator()*b.getNumerator());
x.setDenominator(a.getDenominator()*b.getDenominator());
return x;
}
// ...
void main(){
CFraction b1,b2(3,7),b3(5,8);
b2=b1*3;
b2=3*b1;
}
He said that the above code would be working fine, but if you change the method to the following:
CFraction operator*(CFraction&,CFraction&);
it wouldn't work. Why is that?
Hope you can explain it to me.
Thanks in advance.
-
2You need to read up on const reference binding.SergeyA– SergeyA2016年03月08日 14:38:58 +00:00Commented Mar 8, 2016 at 14:38
-
1Try it and the compiler will tell you. Unless you are using MSVC, then it will keep working as an extension I believe.Baum mit Augen– Baum mit Augen ♦2016年03月08日 14:39:07 +00:00Commented Mar 8, 2016 at 14:39
-
It's impossible to have an no const reference to a literal like 3 in your example for calculation of b2.Garf365– Garf3652016年03月08日 14:43:05 +00:00Commented Mar 8, 2016 at 14:43
2 Answers 2
it wouldn't work. Why is that?
Let's look into your expression:
b2=b1*3;
is equal to:
b2=operator*(b1,3);
as second type is not type of CFraction it has to be converted to it ie:
b2=operator*(b1,CFraction(3));
CFraction(3) creates temporary object of type CFraction. Temporary is not lvalue so cannot be passed as lvalue reference - CFraction & and if you define your function with non const references (aka lvalue references) it would not work in this case.
1 Comment
You are basically asking, "why should my arguments be const?"
There is actually a good reason for this in this scenario. In c++, whenever you have a function argument with a const reference, (amongst other things) it means you can pass in a literal as an argument into that function (assuming the capacity for a type conversion is available).
For example, if you don't use the const reference, you can still do something like:
CFraction b1,b2(3,7),b3(5,8);
b3=b1*b2;
In the prior example, you passed in (non constant) references to objects b1 and b2. That's alright because this expression makes sense. However, you could not do the following:
CFraction b1,b2(3,7),b3(5,8);
b3=b1*3;
Why? Because 3 is a literal. Whenever you don't include the const reference to CFraction, you cannot pass literals into that function as an argument. Using const reference enables you to pass in literal values.
8 Comments
static int i; b3 = b1 * i; - this seems OK? No pesky literals in sight?