C++ operator I/O overloading - c++

I've encountered a strange problem while overloading << operator for a Complex class (The Complex class and overload function are not complete, but the meaning should be the same - BUT if you feel there is missing some important part, just prompt me ;-) ):
class Complex {
float m_fReal;
float m_fImaginary;
public:
Complex();
Complex(float real, float imaginary);
Complex add(Complex) const;
friend std::ostream& operator<<
(std::ostream& out, Complex cComplex);
};
Overload function:
std::ostream& operator<<(std::ostream& out, Complex cComplex) {
out << cComplex.m_fReal << " " << cComplex.m_fImaginary;
return out;
}
Add function:
Complex Complex::add(Complex cComplex) const {
return Complex (m_fReal + cComplex.m_fReal,
m_fImaginary + cComplex.m_fImaginary);
}
Function call in main:
Complex x(1,1), y(2,2);
cout << "x+y=" << x.add(y) << endl;
While the above works, this does not (only parts that differ).
Declaration in Complex class:
friend std::ostream& operator<<
(std::ostream& out, Complex& cComplex);
Definition:
std::ostream& operator<<(std::ostream& out, Complex& cComplex) {
out << cComplex.m_fReal << " " << cComplex.m_fImaginary;
return out;
}
My intention was to pass the Complex class by reference. Can anybody explain to me, what went wrong in this code and why?

You need to accept the object to output by const reference. You're accepting it as a non-const reference to which the return from add cannot be bound.
std::ostream& operator<<(std::ostream& out, const Complex& cComplex) {
This design/behavior is to prevent mistakes where a function expects to mutate the value of a reference parameter, but the reference has been bound to an unnamed temporary object, in other words memory that can't be accessed again, rendering the changes pointless.

Your definition should be
std::ostream& operator<<(std::ostream& out, const Complex& cComplex) {
out << cComplex.m_fReal << " " << cComplex.m_fImaginary;
return out;
}
cComplex needs to be const qualified for you to access its private variables using "."

Related

<< overload operator, why it can't return to just class type(without reference)

so this is a classic cout overloading friend member function. I have a simple question here. why it has to be return to the reference(ostream&)?. Why can't it be return to just ostream?
class Time {
private:
int hours;
int minutes;
public: friend ostream& operator<<(std::ostream &os, const Time& t) { os<<t.hours<< "hours, " <<t.minutes<< "minutes;
return os; //why it can't return to just ostream(witout reference &)
}
That should be:
friend std::ostream &operator<<(std::ostream &os, const Time& t) {
os << t.hours << "hours, " << t.minutes << "minutes;
return os;
}
That must be a reference because you can't copy an ostream object. What would this mean, copying the underlying file? No, no copy.
ostream objects are not copyable. Since they represent 'real world` resources, (consoles and files etc) it doesn't make any sense to copy them.
So because they are not copyable they have to be passed around by reference, so the correct return type from operator<< is a reference, ostream&.

C++ How do I print an object?

I have created a constructor
Location(double xIn,double yIn,string placeIn,int timeIn)
: x(xIn),y(yIn) ...so on {
Say I want to print Location home(x,y,place,time); that's in the main().
How would I do so? I've been searching around and was told to use operator<<. How would I implement this?
UPDATE: After creating some get methods and I tried doing,can't exactly compile it because of the problem
ostream &operator<<(ostream & o, const Location & rhs){
o << rhs.getX() << "," << rhs.getY() << "," << rhs.getPlace() << "," << rhs.getTime();
return o; }
Here is the stencil for overloading operator<<:
class Any
{
public:
friend std::ostream& operator<<(std::ostream& output, const Any& a);
private:
int member;
};
std::ostream&
operator<<(std::ostream& output, const Any& a)
{
output << a.member;
return output;
}
This one possible stencil, there are other possibilities. Search the internet for "c++ stream insertion operator overload example" for other implementations.

How to get THIS when overloading operator in C++

I'm a student learning c++. today, I was making a operator overload function to use it in 'cout'. following is a class that contains name, coordinates, etc.
class Custom {
public:
string name;
int x;
int y;
Custom(string _name, int x, int y):name(_name){
this->x = x;
this->y = y;
}
int getDis() const {
return static_cast<int>(sqrt(x*x+y*y));
}
friend ostream& operator << (ostream& os, const Custom& other);
};
ostream& operator << (ostream& os, const Custom& other){
cout << this->name << " : " << getDis() << endl;; // error
return os;
}
However, this code isn't working because of 'THIS' keyword that I was expecting it points to the object. I want to show the object's name and distance value. How can I solve it? I think it is similar with Java's toString method so that it will be able to get THIS.
Thanks in advance for your answer and sorry for poor english. If you don't understand my question don't hesitate to make a comment.
this is available only in member functions, but your operator<< is not a class member (declaring it as friend does not make it a member). It is a global function, as it should be. In a global function, just use the arguments you are passing in:
ostream& operator << (ostream& os, const Custom& other)
{
os << other.name << " : " << other.getDis() << endl;
return os;
}
Also note os replaced cout in the code above. Using cout was an error - the output operator should output to the provided stream, not to cout always.

Cascading overloaded cout operator error `No match` when used with other overloaded operators

I have overloaded << in my code as a friend function. Even after using braces while cascading there is still the error
error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits =
std::char_traits<char>]((* & std::cout), ((const char*)"complex conjugate is "))
<< c.myComplex::operator~()’
I have a class myComplex
class myComplex
{
private:
float real;
float imaginary;
public:
myComplex();
myComplex(float a,float b);
friend std::ostream& operator<<(std::ostream& iso,myComplex& a);
myComplex operator~() const;
};
The overload for <<, ~and the constructors are as follows,
std::ostream& operator<<(std::ostream& oso,myComplex& a)
{
oso<<a.real<<" + "<<a.imaginary<<"i"<<std::endl;
return oso;
}
myComplex myComplex::operator~() const
{
return myComplex(this->real,-1*this->imaginary);
}
myComplex::myComplex(float a,float b)
{
real = a;
imaginary = b;
}
I use it in main as follows,
Line 1: std::cout << "c is " << c << "\n";
Line 2: std::cout << "a is " << a << "\n";
Line 3: ((std::cout <<"complex conjugate is ")<<(~c))<<"\n";
Line 3: std::cout <<"complex conjugate is "<<~c<<"\n";
Line 1 and 2 work fine, but Line 3 gives the error. If it can cascade for Line 1 and 2 and since ~c also returns an ostream why does it give an error for that?
A temporary object (in this case that returned by operator~()) cannot be bound to a non-const reference. Change argument of operator<<() to be a const reference:
friend std::ostream& operator<<(std::ostream& iso,myComplex const& a);
Because your operator~() returns by value, you are feeding a temporary object into your ostream& operator<< here:
std::cout <<"complex conjugate is "<< ~c <<"\n";
// ^^ HERE! Temporary myComplex value.
The operator takes its 2nd argument by non-const reference myComplex&. A non-const reference cannot bind to a temporary. Change it to
std::ostream& operator<<(std::ostream& oso, const myComplex& a);
Use const myComplex & instead of myComplex &:
friend std::ostream& operator<<(std::ostream& iso, const myComplex& a);
^^^^^
And change the implementation, of course.
Your operator << takes the second parameter by non-const reference, which means it can't bind to a temporary (such as the one returned by ~). Change operator << to accept const myComplex& as the second argument.
It would certainly be weird if the stream-output operator modified its argument anyway.
BTW, do you know that C++ has a built-in class std::complex?

operator<< overloading [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator overloading
I didn't find any thing that could help me in this subject...
I'm trying to over load the << operator, this is my code:
ostream& Complex::operator<<(ostream& out,const Complex& b){
out<<"("<<b.x<<","<<b.y<<")";
return out;
}
this is the declaration in the H file:
ostream& operator<<(ostream& out,const Complex& b);
I get this error:
error: std::ostream& Complex::operator<<(std::ostream&, const Complex&) must take exactly one argument
what and why I'm doing wrong?
thanks
your operator << should be free function, not Complex class member in your case.
If you did your operator << class member, it actually should take one parameter, which should be stream. But then you won't be able to write like
std::cout << complex_number;
but
complex_number << std::cout;
which is equivalent to
complex_number. operator << (std::cout);
It is not common practice, as you can note, that is why operator << usually defined as free function.
class Complex
{
int a, b;
public:
Complex(int m, int d)
{
a = m; b = d;
}
friend ostream& operator<<(ostream& os, const Complex& complex);
};
ostream& operator<<(ostream& os, const Complex& complex)
{
os << complex.a << '+' << complex.b << 'i';
return os;
}
int main()
{
Complex complex(5, 6);
cout << complex;
}
More info here
As noted, the streaming overloads need to to be free functions, defined outside of your class.
Personally, I prefer to stay away from friendship and redirect to a public member function instead:
class Complex
{
public:
std::ostream& output(std::ostream& s) const;
};
std::ostream& operator<< (std::ostream& s, const Complex& c)
{
return c.output(s);
}