Why have to use friend function - c++

I am trying to overload operator '=' and operator '<<' by the same method.
class Vect{
public:
//..
Vect& operator=(const Vect& a);
ostream& operator<<(ostream& out, const Vect& vect);
//..
private:
int *data;
int size;
};
this work
Vect& Vect:: operator=(const Vect& a){
//..
//copy data operator
for(int i = 0; i< size; i++){
data[i] = a.data[i];
}
return *this;
}
however: this code cause error
[Error] 'std::ostream& Vect::operator<<(std::ostream&, const Vect&)' must take exactly one argument
ostream& Vect::operator<<(ostream& out, const Vect& vect){
//.. print vect
}
I am reading "Data structure and algorithms in C++" book part (1.5.4).
They said i have to use class friends for overloading '<<' operator because it is access private members data.
I don't understand why. Overloading '=' operator i also access private member data without using "friend".

When you put a function declaration inside the class definition, it becomes by default a member function, so...
class Vect {
public:
ostream& operator<<(ostream& out, const Vect& vect);
};
...won't compile as it requests creation of a << function that takes too many arguments arguments: any member function operator<< is expected to use *this as the "left hand side" argument, and take one other argument to be the "right hand side".
You have two options:
Replace the above with friend ostream& operator<<(ostream& out, const Vect& vect);, which tells the compiler that the function is a friend of the surrounding class, but not a member thereof. As a non-member, the two arguments it operates on are out and vect - there is no *this object involved. That all works fine, and being a friend the definition also has access to private and protected member data in vect.
Move the operator<< declaration outside the class Vect definition; that also makes it a non-member function, but that doesn't make it a friend.

Overloading '=' operator i also access private member data without using "friend"
operator= is declared as a member function, which can access the private member.
They said i have to use class friends for overloading '<<' operator because it is access private members data. I don't understand why.
The problem is you're declaring operator<< as a member function, which should be declared as a non-member function. That's why you got the error.
operator<< should be a non-member function, because it needs a different type as its left-hand argument, i.e. std::ostream&, instead of Vect& when declared as a member function.
That means, as a non-member function, operator<< couldn't access the private member of the class unless you declare it as friend, such as:
class Vect {
public:
//..
friend ostream& operator<<(ostream& out, const Vect& vect);
//..
Note the above syntax makes operator<< a non-member function now.

Related

Overloading the stream insertion operator

I am trying to overload the stream insertion operator for an assignment. In my header file, I have the following:
friend ostream& operator<<(ostream, Vector);
In my implementation file, I have:
friend ostream& operator<<(ostream& outputStream, Vector& displayMe) {
outputStream << "<" << displayMe.GetVX << "," << displayMe.GetVY << ">";
return outputStream;
}
I am getting an error that says:
"invalid specifier outside a class declaration"
The error is pointing to the line that begins with friend ostream& in my implementation file.
I am new to operator overloading obviously. Am I supposed to define this outside of the class? I am just confused about why I am getting this error and how I go about fixing my code. Any suggestions would be helpful.
You need to declare the ostream<< operator within the Vector class:
class Vector
{
// ...
friend ostream& operator<<(ostream&, Vector&);
};
Notice also that you need to use references in the signature as well.
You don't specify friend in the implementation of the operator.
Also, it's advisable to take the Vector by const-reference here:
ostream& operator<<(ostream&, Vector const&);

friend keyword for operator overloading

I tried to write an simple example for the <<-operator-overloading.
Before, i've never used the keyword "friend". But it does not work without it. What is the mistake i did or why do i need the friend keyword here?
class rational{
public:
rational(double num, double count)
: n(num),c(count){}
rational& operator+=(const rational& b){
this->n+= b.n;
this->c+= b.c;
return *this;
}
friend std::ostream& operator<<(std::ostream& os, const rational& obj)
{
std::cout << obj.n << "," << obj.c << std::endl;
return os;
}
private:
double n;
double c;
};
Thanks
You didn't make any mistake. The friend keyword gives your operator<<() implementation access to private (and protected, if you had any) members of your class.
Note that because it's a friend, operator<<() here is implicitly a free function and not a member function (if it were a member function, it could access private things already!). Because it's declared and defined only inside the class, it can only be found by argument-dependent lookup, but this is fine for operator<< and is a detail you don't have to worry about yet.
You want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming
class T {
public:
void stream_to(std::ostream& os) const {os << obj.data_;}
private:
int data_;
};
and call that from the operator:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.stream_to(os);
return os;
}
or make the operator a friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
so that it can access the class' private parts:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}
You are declaring and defining the operator inside the class, thus without friend it has an implicit first operand of type rational. You wouldn't have such problem if you had declared the operator outside the class, but then you wouldn't have access to n and c.

Type conversion in ostream& operator <<

I have a class entry and an ostream& operator << overwritten for it. I also have an auxiliary class cursor and a type conversion operator entry().
Then, in my main() function I have the following expression:
cout << data[4];
where data[4] is a cursor, but compilation fails with
error: invalid operands to binary expression
What I want is for a compiler to convert data[4] to entry and to use its << operator.
Is there any way to call this ostream operator in an aforementioned way without having to add special methods to entry?
Here are some pieces of code:
class entry
{
friend class cursor;
/*here comes some data*/
public:
friend ostream& operator << (ostream& out, const entry& a);
};
class cursor
{
database* data_;
size_t ind_;
friend class entry;
friend class database;
public:
cursor (database* a, size_t ind);
cursor (const cursor& a);
void operator= (const entry x);
void operator= (const cursor a);
operator entry(); //type conversion
};
and here is what I use in main():
cout << data[4];
When you write:
class entry
{
// ...
friend ostream& operator << (ostream& out, const entry& a);
};
Although this declares operator<< in the enclosing scope, the name lookup rules say that name lookup in that scope does not actually find this function! (Because it has only been declared via friend).
If a function has only been declared via friend, then the only way it can be found is via argument-dependent lookup. See this thread for more detailed explanation of the lookup rules.
The function would be found by:
entry e;
cout << e;
because ADL sees that there is an argument of type entry and so it searches functions that are associated with entry (including friends declared there).
However, cursor c; cout << c; does not include entry in its search list (even though a conversion from cursor to entry exists).
To fix this you need to provide a non-friend declaration of the operator, that is visible at the point of main. For example:
ostream& operator << (ostream& out, const class entry& a);
class entry
{
// ...
friend ostream& operator << (ostream& out, const entry& a);
};
NB. I chose to put the declaration before the class instead of after, because this is also the best way to solve the template friends problem.

which "<<" operator function should be used?

There are two ways of implementing operator "<<" or ">>" function in a project.
1.As a non-member function
2.As a friend
#include<iostream>
using namespace std;
class xxx{
private: int x;
public: xxx(int val=0):x(val){}
int getx(){return x;}
friend ostream& operator <<(ostream& o, xxx& x1);
};
ostream& operator<<(ostream& o, xxx& x1)
{
o<<x1.getx();
return o;
}
ostream& operator <<(ostream& o, xxx& x1)
{
o<<x1.getx();
return o;
}
int main(int argc, char *argv[])
{
xxx x1(5);
return 0;
}
Looks like both non-member and friend function have same signature when implementing, and thus i get compiler error :
"error: redefinition of 'std::ostream& operator<<(std::ostream&, xxx&)' ".
Could anyone please help how to compile the above code.
Also would like to know in which situation should we use non-member "operator =" function over friend "operator =" function.
You seem to be confused -- a friend function is a non-member function. So your friend declaration declares the non-member function and makes it a friend. You then define the (non-member) function twice, which is an error.
The two ways to define (most) overloaded operators is as a member function or a non-member function. You cannot do both for the same operator, and if you define it as a non-member, it may be a friend or not as you prefer (friend is irrelevant)
As for your final question -- you cannot define operator= as a non-member function. It must be a member function. friend is irrelevant.
The two definitions are identical. And in your case, the operator is not accessing private or protected members of the class, so the friend declaration is redundant.

Can ostream overloading be a function member?

I have a class Counter and I want to overload operator << to output the data member of Counter. I tried to make the ostream overloading a member function:
Counter{
public:
std::ostream& operator<<(std::ostream& outStream, const Counter& c);
private:
int count_;
};
std::ostream& Counter::operator<<(std::ostream& outStream, const Counter& c){
outStream << c.count_;
return outStream;
}
But the g++ compiler always outputs the same error:
‘std::ostream& Counter::operator<<(std::ostream&, const Counter&)’ must take exactly one argument
However, if I changed the overloading function to be a friend of the class, it worked all well, like this:
Counter{
public:
friend std::ostream& operator<<(std::ostream& outStream, const Counter& c);
private:
int count_;
};
std::ostream& operator<<(std::ostream& outStream, const Counter& c){
outStream << c.count_;
return outStream;
}
Does this mean that the the stream operator overloading cannot be a member function of a class?
Add a public query method that returns the value of count_, then it does not have to be a friend:
Counter{
public:
int count() const { return count_; }
private:
int count_;
};
std::ostream& operator<<(std::ostream& outStream, const Counter& c){
outStream << c.count();
return outStream;
}
If you put the ostream operator in the class itself then it will not work the way you expect it to. It would be a member function meaning to invoke it one would have to do this: c.operator<<("output") which is obviously not what you mean to do. For it to work as you expect an ostream operator it must be outside the class. You can do this by making it a friend or just put it outside of the class and use getters (accessors) to output the data.
It doesn't have to be a friend, but it can't be a member. Member operators only work when they are inside the class which corresponds to the left-hand operand.
Unfortunately the useful overloads for the streaming output operators ( << ) cannot be class members, because the ostream& must be on the left in use and declaration. They do not need to be friends of the class you wish to stream unless they need access to protected or private members. This means that if you can implement a streaming operator using just public functions such as observers/accessors without declaring it a friend.
In your first Counter class you are declaring a member function of the class that does not seem valid. In the second example of the Counter class you are stating that your operator overload for << , which seems valid, has access to the private members. In the second example the function must still be declared outside the class.
Wikipedia Operators in C and C++ has a good list of possible operator overloads, including the in class << overloads even though they are not very useful. The in class overloads must be called backwards CounterInstance << cout; which is counterintuitive.