Why friend function is preferred to member function for operator<< - c++

When you are going to print an object, a friend operator<< is used. Can we use member function for operator<< ?
class A {
public:
void operator<<(ostream& i) { i<<"Member function";}
friend ostream& operator<<(ostream& i, A& a) { i<<"operator<<"; return i;}
};
int main () {
A a;
A b;
A c;
cout<<a<<b<<c<<endl;
a<<cout;
return 0;
}
One point is that friend function enable us to use it like this
cout<<a<<b<<c
What other reasons?

You have to use a free function and not a member function as for binary operators the left hand side is always *this for member functions with the right hand side being passed as the other parameter.
For output stream operators the left hand side is always the stream object so if you are streaming to a standard class and not writing the stream yourself you have to provide a free function and not a member of your class.
Although it would be possible to provide a backwards stream operator as a member function and stream out like this:
myObject >> std::cout;
not only would you violate a very strong library convention, as you point out, chaining output operations would not work due to the left-to-right grouping of >>.
Edit: As others have noted, while you have to make it a free function it only needs to be a friend if the streaming function cannot be implemented in terms of the class' public interface.

You have no choice -- it has to be a free function.
Note, however, that it need not necessarily be a friend function. It only needs to be a friend if you actually need to grant it private access. For example, I use the following in programming competitions:
template <class A, class B>
std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p)
{
return os << '(' << p.first << ", " << p.second << ')';
}
No need for it to be friend, as first and second are accessible publicly.

A further reason in your example - it has to be a friend because that's the only way to define a free function inside the class definition. If you wanted a non-friend free function, it would have to be defined outside the class.
Why would you prefer to define it in the class? Sometimes it's nice to define all the operators together:
struct SomeClass {
// blah blah blah
SomeClass &operator+=(const SomeClass &rhs) {
// do something
}
friend SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
lhs += rhs;
return lhs;
}
// blah blah blah
// several pages later
};
might be a bit more user-friendly than:
struct SomeClass {
// blah blah blah
SomeClass &operator+=(const SomeClass &rhs) {
// do something
}
// blah blah blah
// several pages later
};
SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
lhs += rhs;
return lhs;
}
This assumes of course that you are defining the related member functions in the class definition, rather that declaring them there and defining them in a .cpp file.
Edit: I've used += and + as an example without really thinking about it, but your question is about operator<<, which doesn't have any closely related operators like operator+ does. But if operator<< calls one or more member functions related to printing, you might want to define it near where they're defined.

You can't. But If you don't want it to be a friend function, make it a free function and implement it in terms of the class' public interface. For eg.
ostream& operator<<(ostream& os, Myclass& obj)
{
return obj.print(os);
}
ostream& MyClass::print(ostream& os)
{
os << val; // for example.
return os;
}

Related

Templates Objects and Primitives

I have the following class template which will accept both primitives and object. However like this I can only print primitives. How can I make it function using both primitives and objects? Thanks
template<class T>
class A
{
private:
vector <T> l;
public:
void print() const
{
for (int i=0;i<.size();i++)
{
cout<<l[i]<<endl; //error here
}
}
};
The reason why you can print primitives is that <iostream> provides overloads for operator<< for them.
To let your template print your classes in the same way, you need to define your own implementation of the operator:
// This implementation puts operator << outside your class.
// Mark it "friend" in MyClass if it needs access to private members of MyClass.
ostream& operator<<(ostream& ostr, const MyClass& myClass) {
// Do the printing based on the members of your class
ostr << myClass.member1 << ":" << myClass.member2;
return ostr;
}
The compiler will detect this operator during template expansion, and use it for printing when you do this:
cout<<l[i]<<endl;
You can put operator<< inside your class as well:
ostream &operator<<(ostream &os) {
ostr << member1 << ":" << member2;
}
I am assuming that here, you want to print an object instead of a variable belonging to a fundamental datatype.
For such cases, you can look at operator overloading in C++(more specifically overloading insertion operator).
For more information about overloading the insertion operator for an object, you can visit this URL
http://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx
Given below is an example about how to go about it
ostream& operator<<(ostream& os, const Datatype& dt)
{
os << dt.a <<" " << dt.b;
return os;
}
Here Datatype is the name of the class and a and b are two private members of a and b which will be printed when you try to print the object.
However, to overload using this technique, do not forget to make this function as a friend function of the class(as given below) as the function requires access the to private members of the class.
friend ostream& operator<<(ostream& os, const Datatype& dt);

Override operators with a left and right parameter

I have the simple setup:
#include<iostream>
class Stuff {};
ostream &operator<<(ostream &lhs, const Stuff &rhs) {
return lhs << "something";
}
int main() {
Stuff stuff;
cout << stuff << endl;
cin.get();
}
where the operator<< function prints the mockup Stuff class to an ostream. What I would like to do though is move that function into the Stuff class itself. As in:
class Stuff {
ostream &operator<<(ostream &lhs, const Stuff &rhs) {
return lhs << "something";
}
};
For the life of me though, I can't figure out how to get this to work. I get the sense that I'm trying to re-define a left associative operator from the right side. Is there any way to do this properly?
The way you've defined it, that function would be a member of Stuff, so if it was allowed in C++ you'd have to call it like this:
Stuff stuff;
stuff.operator<<(std::cout, stuff);
So you don't want that.
A binary operator (like <<) takes two arguments (called operands). If it's a (non-static) member function then it must be a member function taking one parameter, where the left operand is the object that you call the function on, and the right operand is the function parameter. So you could do this:
struct Stuff {
std::ostream& operator<<(std::ostream& o) { return o << something; }
};
Stuff s;
s << std::cout << std::endl;
But you probably don't want that either!
To write std::cout << s the operator must either be a member of the left operand or must be a non-member function, so you cannot make it a member of Stuff.
Maybe what you're trying to do is this:
class Stuff {
friend std::ostream& operator<<(std::ostream& lhs, const Stuff& rhs) {
return lhs << "something";
}
};
A friend function is not a member function, so this is valid.

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.

C++ how to write an operator that isn't a member function?

Anyone got an idea on how to write an operator for a class that isn't a member function of the class?
Just make it a free function, or a friend function. A good example of this is operator<<:
class X {
public:
int x;
}
ostream& operator<< (ostream& os, const X& x) {
os << x.x;
return os;
}
The benefit of making it a friend function is that you have direct access to private members, whereas a free function must access all members via public methods.
Arithmetic operators, stream operators, et cetera are often not members of a class. However, they may need to be friends in order to access private data members.
I prefer not to use friend and to expose methods that can be used by the operators instead. I believe this to be more in keeping with the Open/closed principle, as I could easily add a subtraction operator without editing the class.
These are handy for unit-testing, too (I can "inject" a std::ostringstream to test the output of print(), for instance).
Here is an example:
#include <iostream>
class Number
{
public:
Number(int j)
:i(j)
{
}
void print(std::ostream& os) const
{
os << i;
}
int value() const
{
return i;
}
private:
int i;
};
std::ostream& operator <<(std::ostream& os, const Number& n)
{
n.print(os);
return os;
}
Number operator +(const Number& n, const Number& o)
{
return Number(n.value() + o.value());
}
int main()
{
Number a(4), b(5), c(a + b);
std::cerr << c << std::endl;
}
Just declare the global function with the operator name:
Point operator+(Point& p, Vector& v) {
return new Point(p.x + q.i, p.y + q.j);
}
Basically, you can take the operator out of the class, and add a parameter to the beginning of the parameter list. In many cases, you will also need to declare the operator function as a friend.
For instance
class Foo
{
Foo operator +( Foo const& other );
};
becomes
class Foo
{
friend Foo operator +( Foo const&, Foo const& );
};
Foo operator +( Foo const& first, Foo const& second );
The friend statement allows the operator to still access any private or protected members needed.
Note that there are some restrictions on which operators can be overloaded in this manner. See this article for such a list.

Stream Insertion Operator overloading

Im really unsure how to call the function:
friend ostream& operator<<(ostream& out, stack::myItem& theItem);
that is public to my stack object:
class stack
{
public:
stack(int capacity);
~stack(void);
void method1();
...
private:
struct myItem
{
int item;
};
...
public:
friend ostream& operator<<(ostream& out, stack& s);
friend ostream& operator<<(ostream& out, stack::myItem& theItem);
};
It's no different than using stream operator << for any other type (it is called operator overloading for a reason).
However, outputting should not modify an object, hence you really should pass it by const reference (otherwise calls with temporaries would fail to compile).
friend ostream& operator<<(ostream& out, const stack& s);
friend ostream& operator<<(ostream& out, const stack::myItem& theItem);
This operator is a classic binary operator.
// Say I have an operator declared like this:
return_type operator#(left_type lhs, right_type rhs);
// Then the invocation is done this way:
left_type L;
right_type R;
return_type result = L # R;
In the case of the streaming operator, it is a bit special since the left hand argument and the return type actually have the same type (and indeed, will refer to the same object, albeit at different times). This has been done to allow chaining.
// Chaining
std::cout << "<Output> " << 1 << std::endl;
// Which can be analyzed like such
operator<<(
operator<<(
operator<<(
std::cout ,
"<Output> "
),
1
),
std::endl
);
As you can see, the syntax merely allows a convenient invocation. One might note that the order is very well defined, it is a strict left to right evaluation.
So with your object, it would become:
stack s;
std::cout << s << std::endl;
Just like that!
Call it from where? As it's coded only the class knows about the private struct. No code external to the class could use that method since it couldn't create an instance of the struct. Marking it as friend doesn't do you much good.