1

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.

asked Mar 8, 2016 at 14:34
3
  • 2
    You need to read up on const reference binding. Commented Mar 8, 2016 at 14:38
  • 1
    Try it and the compiler will tell you. Unless you are using MSVC, then it will keep working as an extension I believe. Commented 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. Commented Mar 8, 2016 at 14:43

2 Answers 2

5

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.

answered Mar 8, 2016 at 14:48
Sign up to request clarification or add additional context in comments.

1 Comment

Better use the proper term 'bind' (instead of vague 'passed as lvalue reference')
0

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.

answered Mar 8, 2016 at 14:51

8 Comments

Unneccessary focus on literals.
@SergeyA It doesn't make the response incorrect. This is a supplementary answer to the information already provided by Slava.
@SergeyA: Seems completely relevant.
@BarryTheHatchet, it makes it seems that if not for literal, it would work fine. For example, static int i; b3 = b1 * i; - this seems OK? No pesky literals in sight?
@SergeyA: Discussing A⇒C doesn't prohibit also B⇒C. Yes, this answer could be broader, but the other one does that quite well. This one is specific to the question. I think, in concert, they are both completely appropriate as-is.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.