Creating a toString()

Jan 18, 2011 at 11:43pm
Hi!
I'm wondering how to override the operator<< because it doesn't seem to work for me. I'm trying to make it just output a string as a test but it just outputs some weird address(like 15x15ff4558 or something).

My function looks like this:
1
2
3
4
5
6
7
string toString() {
		return "Hello World!";
	}
	
	ostream& operator<< (LinkedList& obj) {
		return cout << obj.toString();
	}


and called as such:
1
2
3
4
5
6
7
int main() {

	LinkedList* list;
	list = new LinkedList();
	cout << list << endl;
	return 0;
}


And yes, I am a complete newbie so I probably screwed something simple up >.<
Appreciates any help I can get! :)

Thanks
Jan 18, 2011 at 11:46pm
list is a pointer. And the stream output operator is printing the address of that pointer. If you want to print the object itself, you need to dereference the pointer.
Jan 19, 2011 at 12:09am
Yeah... like this?
1
2
3
4
5
6
7
int main() {

	LinkedList* list;
	list = new LinkedList();
	cout << &list << endl;
	return 0;
}


Tried that, still gives me the address. And I tried with *list aswell but that gives me huge amounts of compiling errors >.<
Jan 19, 2011 at 12:59am
Can we see more of your code?
Jan 19, 2011 at 1:17am
Sure thing, it's just a basic class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

class LinkedList {

public:
	string toString() {
		return "Hello World!";
	}
	
	ostream& operator<< (LinkedList& obj) {
		return cout << obj.toString();
	}

};

int main() {

	LinkedList* list;
	list = new LinkedList();
	cout << list << endl;
	return 0;

}
Jan 19, 2011 at 1:26am
1
2
3
ostream& operator<< (LinkedList& obj) {
	return cout << obj.toString();
}


This is not a correct definition of the operator. It takes two arguments, one being the left side (the stream) and the other being the right side (the object) like so:

1
2
3
ostream& operator<< (ostream& stream, LinkedList& obj) {
    return stream << obj.toString();
}
Jan 19, 2011 at 2:45am
It should also take a const reference, and the insertion operator should not be a member of the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

class LinkedList {

public:
	string toString() const {
		return "Hello World!";
	}
	
};

ostream& operator<< ( ostream& outs, const LinkedList& obj ) {
	return outs << obj.toString();
}


int main() {

	LinkedList* list;
	list = new LinkedList();
	cout << *list << endl;
	return 0;

}

Notice how the list was properly dereferenced. The other option is to write the insertion operator to take a pointer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

class LinkedList {

public:
	string toString() const {
		return "Hello World!";
	}
	
};

ostream& operator<< ( ostream& outs, const LinkedList* obj ) {
	return outs << obj->toString();
}


int main() {

	LinkedList* list;
	list = new LinkedList();
	cout << list << endl;
	return 0;

}

It depends on how you plan to use it. Heck, you could overload it both ways if you want.

Hope this helps.
Jan 19, 2011 at 12:12pm
Thank you everyone!! It works now :)
1
2
3
ostream& operator<< ( ostream& outs, const LinkedList* obj ) {
	return outs << obj->toString();
}


I tried this, both with the 2 arguments aswell as taking a pointer and then use the -> to access its value but obviously it didn't work since I had the function inside the class and it kept telling me that the function needed exactly 1 argument.

How come it shouldn't be inside the class? :o I was taught that, for instance, the operator= should be inside the class..
Big thanks once again!
Jan 19, 2011 at 9:36pm
It depends on the function.

The assignment, array subscript, and function-call operators must appear inside a class definition.
The stream operators must appear outside a class definition[1].
Other operators may appear wherever you find it most convenient.

See also http://en.wikipedia.org/wiki/Operators_in_c_and_c%2B%2B

[1] Well, you can put stream operators inside the class definition by declaring them with the friend keyword, but this is essentially the same thing. The difference from other operators is that the first argument to the I/O operators must be an iostream, not the object.

Glad to have been of help. :-)
Topic archived. No new replies allowed.