How to get THIS when overloading operator in C++ - 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.

Related

Dealing with operator overload method as a friend

I tried to create simple class and to overload some of it's operators, however, i failed at the very beginning, here's my code:
#include <iostream>
class Person
{
char *firstName;
char *lastName;
int age;
friend std::ostream &operator<<(std::ostream &, const Person &);
public:
Person() : firstName("Piotr"), lastName("Tchaikovsky"), age(10) {}
Person(char* f, char* l, int a)
{
this->firstName = f;
this->lastName = l;
age = a;
}
std::ostream &operator<<(std::ostream& out, const Person &p)
{
out << p.firstName << " " << p.lastName;
return out;
}
};
int main()
{
Person a;
getchar();
getchar();
}
So, before i created this operator overloading function i used debugger to see if constructor is going to work, and it worked, since default values were given correctly to the variable a i created, after that, all i did was that i created function that overloads the operator << and it is a friend function of my class, since i am taught that it is a good thing to do due to the type of the first parameter of overloading function, however, when i try to run this (NOTE: i have not tried to print out anything yet, i wanted to check if everything works fine first) it gives me errors saying:
"too many parameters for this operator function",
"binary 'operator <<' has too many parameters" and
" 'Person::operator<<' :error in function declaration; skipping function body"
however, i can't find any problems with function declaration, and i cannot possibly see how two parameters can be too many for this function. Any help appreciated!
You declare the friend function as a global non-member function. Then you define a member function.
Move the definition of the operator<< function to outside the class:
class Person
{
...
friend std::ostream &operator<<(std::ostream &, const Person &);
...
};
std::ostream &operator<<(std::ostream& out, const Person &p)
{
out << p.firstName << " " << p.lastName;
return out;
}
Or alternatively define the friend function inline:
class Person
{
...
friend std::ostream &operator<<(std::ostream &, const Person &)
{
out << p.firstName << " " << p.lastName;
return out;
}
...
};

Error with << operator overload returning a std::string

I'm having troubles understanding the reason why the compiler accuses error, when the return type of a << operator overload is std::string. Could you please help me understand?
Bellow is an reproducible example, which gives a gigantic error.
class XY
{
int X__;
int Y__;
public:
XY(int x, int y):X__(x), Y__(y){}
~XY(){}
std::string operator<<(const XY_cartesiano& c)
{
std::stringstream ss;
ss << "{ " << X__ << ", " << Y__ << " }";
return ss.str();
}
int x() const{return X__;}
int y() const{return Y__;}
};
void main()
{
XY a(1,2);
std::cout << a;
}
Let's take something like this as an example:
cout << "My number is " << 137 << " and I like it a lot." << endl;
This gets parsed as
((((cout << "My number is ") << 137) << " and I like it a lot.") << endl);
In particular, notice that the expression cout << "My number is " has to evaluate to something so that when we then try inserting 137 with << 137 the meaning is "take 137 and send it to cout."
Imagine if cout << "My number is " were to return a string. In that case, the << 137 bit would try to use the << operator between a string on the left-hand side and an int on the right-hand side, which isn't well-defined in C++.
The convention is to have the stream insertion operator operator << return a reference to whatever the left-hand side stream is so that these operations chain well. That way, the thing on the left-hand side of << 137 ends up being cout itself, so the above code ends up essentially being a series of chained calls to insert things into cout. The signature of these functions therefore usually look like this:
ostream& operator<< (ostream& out, const ObjectType& myObject) {
// ... do something to insert myObject into out ... //
return out;
}
Now, everything chains properly. Notice that this function is a free function, not a member function, and that the left-hand side is of type ostream and the right-hand side has the type of your class in it. This is the conventional way to do this, since if you try overloading operator << as a member function, the left-hand side will be an operand of your class type, which is backwards from how stream insertion is supposed to work. If you need to specifically access private fields of your class in the course of implementing this function, make it a friend:
class XY {
public:
...
friend ostream& operator<< (ostream& out, const XY& myXY);
};
ostream& operator<< (ostream& out, const XY &myXY) {
...
return out;
}
Correct way to overload << operator in your case is
ostream& operator<<(ostream& os, const XY& c)
{
os << c.X__ <<" "<< c.Y__ ;
return os;
}
You have overloaded operator<< in a way that's incompatible with the conventions you must follow when you intend to use the operator with a std::ostream object like std::cout.
In fact, your operator<<'s signature has nothing to do with streams at all! It is just a member function of XY which takes another XY (which it then does not use), returns a string and has an unsual name. Here's how you would theoretically call it:
XY a(1,2);
XY b(1,2);
std::string x = (a << b);
The correct way to overload operator<< for use with streams is to make the operator a non-member function, add a stream reference parameter and return a stream reference to the stream argument. You also do not need a string stream; you write directly to the stream you get:
#include <iostream>
class XY
{
int x;
int y;
public:
XY(int x, int y) : x(x), y(y) {}
int X() const { return x; }
int Y() const { return y; }
};
std::ostream& operator<<(std::ostream& os, XY const& c)
{
os << "{ " << c.X() << ", " << c.Y() << " }";
return os;
}
int main()
{
XY a(1,2);
std::cout << a;
}

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.

operator << overloading often fails if operator is const?

If I want to overload the << operator to use cout on a class, it should look like this:
template <typename coutT>
friend ostream& operator << (ostream &, const vector3D<coutT>&);
inside the class, and
template <typename coutT>
ostream& operator << (ostream & os,const vector3D<coutT>& v)
{
os << "x: " << v.x<< " y: " << v.y << " z: " << v.z;
return os;
}
on the outside. Please take note of the const at the second operand.
This sample of code works just fine. Now to the problem.
If I were to write the overload function using the getters for the fields, instead of addressing them directly (since operator<< is a friend), my compiler would throw an error:
template <typename coutT>
ostream& operator << (ostream & os,const vector3D<coutT>& v)
{
os << "x: " << v.getX() << " y: " << v.getY() << " z: " << v.getZ();
return os;
}
The error:
(VisualStudio2012) errorC2662: "this-pointer cannot be converted from "const vector3D" in "vector3D&""
An important note is that deleting the "const" at the second operand so that it's like
ostream& operator << (ostream & os,vector3D<coutT>& v){...}
ended compiler errors, but since I don't want to change v, it should really be a const.
I should also mention that I think it may have to do with method calls in general, but I'm not sure.
edit:
So it is solved, declaring functions as const sticks to const-correctness.
The error message explains it in the way that it cannot cast the const type to a non-const one.
btw.: I'm actually impressed about the quick responses.
The getter function should be declared const if you want to use it that way.
For example
int getValue() const {
return x;
}
Complete example:
#include <iostream>
#include <vector>
using namespace std;
class Foo {
int x;
public:
Foo(int a) : x(a) {
}
int getValue() const {
return x;
}
friend ostream & operator<<(ostream & out, const Foo & foo) {
return out << foo.getValue();
}
};
int main() {
vector<Foo> foo_vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (vector<Foo>::iterator it = foo_vec.begin(); it != foo_vec.end(); it++) {
cout << *it << ", ";
}
return 0;
}
Your problem is that you didn't mark the get functions const:
They need to look like this:
double getX() const;
You need to make the accessor functions const:
struct V
{
int getX() const { /* ... */ }
^^^^^
};
Only const member functions can be invoked on constant object values. In turn, const member functions cannot mutate the object. Thus const-correctness guarantees that a constant value cannot be mutated by invoking any of its member functions.

<< operator overloading as a class method in c++

I want to overload the << operator for my class Complex.
The prototype is the following:
void Complex::operator << (ostream &out)
{
out << "The number is: (" << re <<", " << im <<")."<<endl;
}
It works, but I have to call it like this: object << cout for the standart output.
What can I do to make it work backwards, like cout << object?
I know that the 'this' pointer is by default the first parameter sent to the method so that's why the binary operator can work only obj << ostream. I overloaded it as a global function and there were no problems.
Is there a way to overload the << operator as a method and to call it ostream << obj?
I would just use the usual C++ pattern of free function. You can make it friend to your Complex class if you want to make Complex class's private data members visible to it, but usually a complex number class would expose public getters for real part and imaginary coefficient.
class Complex
{
....
friend std::ostream& operator<<(std::ostream &out, const Complex& c);
private:
double re;
double im;
};
inline std::ostream& operator<<(std::ostream &out, const Complex& c)
{
out << "The number is: (" << c.re << ", " << c.im << ").\n";
return out;
}
You could write a free stand operator<< function, try:
std::ostream& operator<< (std::ostream &out, const Complex& cm)
{
out << "The number is: (" << cm.re <<", " << cm.im <<")." << std::endl;
return out;
}
You can define a global function:
void operator << (ostream& out, const Complex& complex)
{
complex.operator<<(out);
}