javabram
javabram

Reputation: 75

My understanding of friend functions

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

Answers (5)

alain
alain

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;
}
  • some forward declarations added
  • int passed by value instead of by reference
  • missing semicolon after class declaration
  • class instead of Class
  • return corrected

Note 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

aliasm2k
aliasm2k

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

Jason
Jason

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

ForceBru
ForceBru

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

davidhigh
davidhigh

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

Related Questions