Reputation: 109
I am going through operator overloading in C++ and have a question.
What if both friend and member operator overloaded functions are present? Which will be called?
A minimal example for the +
operator is below.
#include <iostream>
class myTime
{
private:
int mm,hh;
public:
myTime(): mm(0), hh(0) {}
myTime(int mm1, int hh1) :mm(mm1), hh(hh1) {}
myTime( const myTime & ref) : mm(ref.mm), hh(ref.hh) {}
friend myTime operator +(myTime &t1, myTime &t2);
myTime operator+ (const myTime &ref);
void display() { std:: cout << " Hrs = " << hh << " mins = " << mm << std::endl;}
};
myTime operator + (myTime &t1, myTime &t2)
{
int mm2, hh2;
std::cout << "Friend Operator" << std::endl;
mm2 = (t1.mm + t2.mm) %60;
hh2 = (t1.mm + t2.mm)/60 + (t1.hh + t2.hh);
return (myTime(mm2,hh2));
}
myTime myTime::operator+ (const myTime &ref)
{
int mm2, hh2;
std::cout << " Member operator" << std::endl;
mm2 = (ref.mm + mm)%60;
hh2 = (ref.mm + mm)/60 + (ref.hh + hh);
return (myTime(mm2,hh2));
}
int main()
{
myTime t1(30,3);
myTime t2(50,4);
myTime t3;
t3 = t1+t2;
t3.display();
}
When run on my machine (gcc 4.8.3 Windows), the friend function is called. Will this be the same on all machines?
Edit
With the +
operator changed to const
the member operator is executed.
public:
myTime(): mm(0), hh(0) {}
myTime(int mm1, int hh1) :mm(mm1), hh(hh1) {}
myTime( const myTime & ref) : mm(ref.mm), hh(ref.hh) {}
friend myTime operator +(const myTime &t1, const myTime &t2);
myTime operator+ (const myTime &ref);
void display() { std:: cout << " Hrs = " << hh << " mins = " << mm << std::endl;}
};
again why?
Upvotes: 0
Views: 232
Reputation: 23681
In your edit, the operators still differ by const
qualification. The member function is not const
(and thus effectively operates on non-const left-hand-side and const right-hand-side).
These are all ambiguous:
No const:
friend myTime operator+(myTime &t1, myTime &t2);
myTime operator+(myTime &ref);
Const lhs:
friend myTime operator+(const myTime &t1, myTime &t2);
myTime operator+(myTime &ref) const;
Const lhs vs const rhs ("similar conversions"):
friend myTime operator+(const myTime &t1, myTime &t2);
myTime operator+(const myTime &ref);
Const rhs vs const lhs ("similar conversions"):
friend myTime operator+(myTime &t1, const myTime &t2);
myTime operator+(myTime &ref) const;
Const rhs:
friend myTime operator+(myTime &t1, const myTime &t2);
myTime operator+(const myTime &ref);
All const:
friend myTime operator+(const myTime &t1, const myTime &t2);
myTime operator+(const myTime &ref) const;
Not ambiguous: Every distribution of const
except the above, i.e. every distribution of const
where the functions differ in number of const
s.
Upvotes: 2
Reputation: 797
No, it will give you an error that the call is ambiguous. It was only able to resolve it in your example because one function uses const
while the other doesn't, which is part of the signature. Try this instead:
#include <iostream>
class myTime
{
private:
int mm,hh;
public:
myTime(): mm(0), hh(0) {}
myTime(int mm1, int hh1) :mm(mm1), hh(hh1) {}
myTime( const myTime & ref) : mm(ref.mm), hh(ref.hh) {}
friend myTime operator +(myTime const&t1, myTime const&t2);
myTime operator+ (const myTime &ref) const;
void display() { std:: cout << " Hrs = " << hh << " mins = " << mm << std::endl;}
};
myTime operator + (myTime const& t1, myTime const& t2)
{
int mm2, hh2;
std::cout << "Friend Operator" << std::endl;
mm2 = (t1.mm + t2.mm) %60;
hh2 = (t1.mm + t2.mm)/60 + (t1.hh + t2.hh);
return (myTime(mm2,hh2));
}
myTime myTime::operator+ (const myTime &ref) const
{
int mm2, hh2;
std::cout << " Member operator" << std::endl;
mm2 = (ref.mm + mm)%60;
hh2 = (ref.mm + mm)/60 + (ref.hh + hh);
return (myTime(mm2,hh2));
}
int main()
{
myTime t1(30,3);
myTime t2(50,4);
myTime t3;
t3 = t1+t2;
t3.display();
}
Upvotes: 3