Reputation: 75
Sometimes a non-member function may need access to the private members it's taking in as a agrument.
A friend
function is a non-member function that gives private access to the classes it's friends with.
Class X{
int number;
public:
X& operator+=(const X& rhs);//a += b is a.operator(b)
friend int& operator+=(int& addthis, const X& rhs);//add this += b is I don't know what lol
}
X& operator+=(const X& rhs){
this->number = this->number + rhs.number;
}
int& operator+=(int& addthis, const X& rhs){
addthis = addthis + rhs.number;
return *this;
}
What I read is that if I wanted to do +=
to an object, object += int
, just overload the +=
operator, but what if the int
came before the object. Say int += object
? Than I would have to write it as a friend
function, and that's where I get a little lost. Why can't I just write int& operator+=(int& addthis, const X& hrs);
as a member function? I assume a friend
function can work with other classes since it's a non-member function, so it's not assigned to any specific class?
I'm sorry I just don't understand why I would use friend
function over making it a member function. Really would appreciate any feedback, thank you.
Upvotes: 4
Views: 263
Reputation: 12047
The reason why the operator int += X
has to be a free function is that the compiler only searches for applicable member operators in the lhs type, and not in the rhs type. Since int
is not a type that can be extended, you can't define this operator as a member function.
You were almost there, just a few errors:
class X;
int operator+=(int addthis, const X& rhs);
class X{
int number;
public:
X& operator+=(const X& rhs);//a += b is a.operator(b)
friend int operator+=(int addthis, const X& rhs);//add this += b is I don't know what lol
};
X& X::operator+=(const X& rhs){
this->number = this->number + rhs.number;
return *this;
}
int operator+=(int addthis, const X& rhs){
addthis = addthis + rhs.number;
return addthis;
}
int
passed by value instead of by referenceclass
instead of Class
return
correctedNote that X += int
is a member function, while int += X
is a free function, declared a friend
of the class X.
Using a free function for int += X
is the only solution that allows to use the operator as usual, like:
X x;
int i = 2;
i += x;
Upvotes: 1
Reputation: 901
Consider you implemented operator overloading as member function and performed something like x += y
where both x
and y
are objects of the class which has the operator +=
overloaded.
Compiler parses x += y
as x.operator+=(y)
which is fine as both operands x
and y
are of the same class which has the operator +=
overloaded.
Now consider an expression like 2 += y
(this may be insane, but I am trying explain why operator overloading with friend functions may be at time beneficial over operator overloading with member functions)
Since, the expression 2 += y
will be parsed by compiler as 2.operator+=(y)
, an error is raised. Maybe 2
may get converted to an object of the class using constructor for conversion; (Single argument constructors can be used for conversion) but that is not the point here.
Using friend function to overload the operator calls the above expression 2 += y
as operator+=(2, y)
which works fine.
Upvotes: 1
Reputation: 3917
The friend
modifier is just meant to expose private
data. Normally, you wouldn't define a friend
function as a non-member if it only depends on the private data of a class it can be defined as a member function for.
A better example would be ostream::operator<<
or istream::operator>>
.
Upvotes: 0
Reputation: 44838
As far as I understand, you can't have operator*
, operator+
or operator+=
or any of operator@
where @
is some math operator that returns something other than an instance of your class right in the definition of your class.
In real world, it would be quite odd to add an integer to an integer and get an apple as a result. The same should apply to classes in C++. A member function is, well, a property of the class, a function that represents whatever can be done to the object of this class. Operators are special. They represent operations that sort of can't be made easier (what will you use to code an addition operator using the +
sign instead of operator overloading?). They represent the very basic operations and thus should return an instance of the class they're members of.
Upvotes: 2
Reputation: 15478
You can enable the operator+=
for int
and other integral types via a user-defined conversion in your class X
:
struct X{
int number;
operator int() const
{
return number;
}
//...
}
Of course, this doesn't give you exactly the same behaviour as your friend
-approach, as other functions could also use the conversion. Nevertheless, I guess this is what you are looking for, as otherwise you would need to define as well operator-=
, operator*=
and so on.
Upvotes: 2