which "<<" operator function should be used? - c++

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.

Related

Overloading insertion << operator

Hello I am trying to overload the insertion operator but there is an error in my compiler when initializing it.
In the .h file
class Zfraction{
public:
friend std::ostream& operator<<(std::ostream& display, Zfraction const& b);
}
in the .cpp
std::ostream& Zfraction::operator<<(std::ostream &display, Zfraction const& b){
}
There is the output
Overloaded 'operator<<' must be a binary operator (has 3 parameters)
Do you have any idea ?
The header in the .cpp file is wrong. By using the scope resolution operator, ::, you're indicating that the operator that you're overloading is a member function of the Zfraction class. This is not true. Although friend declarations must take place inside of the class that they are establishing friendship with, they are not member functions (in other words, they don't have access to a *this pointer). Thus, you need to change the .cpp file to the following:
std::ostream& operator<<(std::ostream &display, Zfraction const& b){
/* Provide your implementation here. */
}

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.

Why have to use friend function

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.

What is meant by non-member operator overloading

I was recently going over an article on operator overloading in which it mentioned non-member operator overloading. I would appreciate it if someone could explain what is meant by non-member operator overloading with an example. I know what member operator overloading is (A method in a class which overloads an operator type (binary..etc) . I came across this post on SO which makes me believe that the purpose of non-member operator overloading is to handle operator overloading in which the first parameter is a not a class and is simply a native type. Any links or examples that explain what non-member operator overloading is would definitely be appreciated.
It means you can overload out-of-class:
struct X { int data; };
bool operator<(X const& a, X const& b)
{
return a.data < b.data;
}
This is useful for assymetrical overloading, where the left operand doesn't need to be your own type:
bool operator<(int a, X const& b)
{
return a < b.data;
}
A common idiom here is to combine it with in-class definition and friend declaration:
struct X
{
int data;
friend bool operator<(X const& a, X const& b) { return a.data<b.data; }
friend bool operator<(int a, X const& b) { return a<b.data; }
};
Here, operator< is still technically non-member.
Another useful side-effect of this, as pointed out by DrewDormann below, is that the (X const&, X const&) will apply to any operands that are implicitly convertible to X const&, not just expressions of that exact type.
the most common way is to overload operator<< that will be called on std::cout:
namespace X {
class MyClass {
...
};
}
std::ostream& operator<< (std::ostream&, const X::MyClass&);
this is called on std::ostream member so you don't define it inside your class.
however sometimes the functionality cannot be achieved via the public interfaces (because your operator needs access to data representation).

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.