Reputation: 526
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?
Upvotes: 0
Views: 231
Reputation: 4659
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.
Upvotes: 1
Reputation: 7339
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.
Upvotes: 3
Reputation: 2713
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;
.
Upvotes: 0
Reputation: 208323
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?
Upvotes: 7