0

I'm have a bit problem with operator overloading. I have two classes.

#include <iostream> using namespace std; class Meter; //Forward declaration class Inch{ private: double inches; public: Inch() : inches(0) {} Inch(double i) { inches=i; } friend Inch operator+ (const Meter& m, const Inch& i); void out(){ cout << "Inch:" << inches << "\n"; } double getInches() const { return inches; } }; 

and

class Meter{ private: double meter; public: Meter() : meter(0) {} Meter(double m) { meter=m; } Meter operator+ (const Inch& i) { return Meter(meter + i.getInches() * 0.0254); } void out(){ cout << "Meter:" << meter; } double getMeter() const { return meter; } }; Inch operator+ (const Meter& m, const Inch& i) { return Inch(m.getMeter()/0.0254 + i.getInches()); } 

In main I have one of each of these classes. I need to add them together with the order : m + i; So m must be the first object. In order to do that, I used friend function in order to use two objects as a parameter.

Inch i(6.4), resultInch; Meter m(14), resultMeter; i.out(); m.out(); resultMeter = m + i; resultMeter.out(); resultInch = m + i; resultInch.out(); 

With the above, resultMeter holds the correct value, but when I put resultInch compiler gives the "error no match for bla bla bla".

What am I missing?

3
  • 3
    Instead of different classes for Inch and Meter, create one class Length with member functions to get meters and inches and any other unit. Just my opinion. Commented Feb 25, 2013 at 19:26
  • nop i need to create different classes. Commented Feb 25, 2013 at 19:30
  • A few things unrelated to your problem: constructors of both classes taking double should probably be marked explicit, also use constructor initializer lists to init the member variables. Why is Inch operator+ (const Meter& m, const Inch& i) a friend? It's calling public member functions. Meter::operator+ should be a const member function since it does not modify the Meter object. Commented Feb 25, 2013 at 19:34

4 Answers 4

7

The problem is that both these two operators are overloads for the exact same + in code. You can either use one or another, but not both in the same program.

Inch operator+ (const Meter& m, const Inch& i); class Meter{ Meter operator+ (const Inch& i); }; 

Consider what would happen if you had one Meter m; and Inch i; and you try to add them with m + i, which operator implementation should be called?

Sign up to request clarification or add additional context in comments.

14 Comments

so do i need to create Meter.h and Inch.h ?
@mertmetin: No, you cannot provide both operators in the same program (not header, not translation, but program). What is, to you, the result of adding a meter and some inches? Is that a meter distance? an inch distance? Decide that, and implement a single operator+ that takes the appropriate arguments and returns the correct type.
@mertmetin: That does not mean that there are two operator+, only that the result of the single operator+ needs to be convertible to both Inch and Meter.
@mertmetin: That is for you to define, not for me. I personally would follow Benjamin's suggestion, meters and inches are not real entities, the entity is the length that can be measured in either meters or inches.... (Actually, I am a strong believer in SI, and consider that the imperial system should banish, if that serves as an answer :)
@mertmetin: I can give you probably two or three ways that will make that compile and will have you fail the assignment. I feel that you don't quite understand what is being asked, and until you understand what is really asked. You should work on that first. Note that it is simpler to just provide you with one of those solutions than argue about it, but that won't help you.
|
3

C++ cannot overload on return value. So when you want to be able to say:

meters = meters + inches; 

and

inches = meters + inches; 

both meters + inches are the same function. I second the recommendation to write one length class with a units attribute and conversion functions. But lacking that, I recommend you write conversion operators between your two length classes. Then only one addition function is needed (you should still write two: meters + meters and inches + inches) and the types can be converted back and forth.

Comments

1

Remove operator+ from both classes. Create proxy class which will be used as the result of addition:

class ProxyMeterInch { private: double op1, op2; public: friend ProxyMeterInch operator+(Meter m, Inch i) { ProxyMeterInch r; r.op1 = m.getMeter(); r.op2 = i.getInch() * 0.0254; // I tend to keep it in meters as I am European return(r); } operator Meter() const { return(op1 + op2); } operator Inch() const { return((op1 + op2) / 0.0254); } }; 

You get the idea. Depending on the type you are trying to assign to correct conversion operator will be selected.

4 Comments

Sorry but this is not what i'm looking for
Try it ;). And then tell me this is not an answer you are looking for. This is the closest I know to overloading on return type (which is not supported by the language itself).
i just need two classes Inch and Meter. in main i create 2 inch and 2 meter objects . Inch i(6.4), resultInch; Meter m(14), resultMeter;
and try to make work this resultMeter = m + i; resultMeter.out(); resultInch = m + i; resultInch.out();
0

Ok, so I assume it's

Inch resultInch = m + i; // not Meter resultInch (...) 

It is equivalent to:

Inch resultInch = (Meter)m.operator+(i); 

and you have no way of converting between Meter and Inch.

Try changing it to Inch resultInch = i + m;.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.