Overloading insertion << operator - c++

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. */
}

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&);

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.

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.

C++ - must friend functions be defined in the header file?

I want to overload the operator << in one of my classes.
The signature goes like this:
friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
When I try to define it in the .cpp file it says that the operator<< exactly takes 1 argument, however, when I define it in the .h, it compiled/works fine.
This is how I define it in the .cpp file :
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... }
Does it have anything to do with friend functions needing to be defined in header files?
It can be defined in a cpp file, but it needs to at least be declared in a header file, otherwise all places where you want to use it will only see the stuff the stream itself gives you, not your overload.
// .h and in class
friend std::ostream& operator<<(std::ostream& os, MyClass const& v);
// .cpp
std::ostream& operator<<(std::ostream& os, MyClass const& v){
// print it
}
The problem is with the way you're defining it. It's not a member of the class, it's just a friend of the class. You need to drop the Annuaire:: prefix. So, change this:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ...
to this:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj){ // ...
The reason for the error message is that Annuaire::operator<<(std::ostream& os, const Annuaire& obj) would expect three arguments: the Annuaire instance that it's called on (as this), and and two additional arguments (os and obj).
As mentioned in David's answer, in this case the operator is not a member function, it is merely a friend function in the same namespace. This pointed me in the right direction in solving a very similar issue.
I'm posting this answer because it wasn't immediately obvious to me. Maybe because the implementation file where I was adding the operator wasn't fully enclosed in the namespace, and used a using-directive instead.
Shouldn't be relevant but I'm using VS2013.
//Foo.h
namespace Bar{
class Foo
{
public:
Foo();
private:
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
}
//Foo.cpp
using namespace Bar; //won't apply to the operator definition
Foo::Foo(){}// doesn't require the Bar qualifier because of the using-directive
//the operator required the Bar namespace qualifier
std::ostream & Bar::operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}
Friend functions, even if they seem to be declared inside the class are not member functions but rather namespace level functions (in the enclosing namespace). In your code you declare the friend function correctly, but you try to define it as a member function of the class:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){
That definition would be for a member function of Annuaire, called operator<<, that takes two arguments, which is invalid as operator<< can be overloaded in one of two ways: as a free function taking two arguments (left hand side and right hand side) or as a member function of the class that appears in the lhs of the expression taking an argument of the rhs type. In this particular case, since the lhs is std::ostream and you cannot modify it, you are left with the only option of using a free function:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
No such restriction; you're probably just writing it wrong. Should be something like this:
class Foo
{
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
std::ostream & operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}