Sign in to follow this  

Creating a function for stream objects

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Question: How do you create a function/class that can be called using a stream? Something like this: class Cat { public: function operator<<(); // <- I know this is wrong private: string s1; int i1; }; function operator<<() { output the varibles to a ostream } main() { cout << Cat; } (yes, I know the code wont compile and doesn't initialize data, etc... I just someone to explain how to use << so I can have my classes save there data to a ostream using something like this) I have looked everywhere, this site and others, and can find no clear cut example (maybe Im looking in the wrong places...)

Share this post


Link to post
Share on other sites
#include <iostream>
#include <string>

class Cat
{

public:

// member functions

private:

std::string descriptiveName;
int anotherDescriptiveName;
};

std::ostream& operator<<(std::ostream& stream, const Cat& cat)
{
// output the varibles to a ostream
return stream;
}

int main()
{
Cat c;
std::cout << c;
}



Enigma

EDIT: forgot to make the cat parameter of operator<< const.

Share this post


Link to post
Share on other sites
Since all the variables are private, you'll also want to have public get methods or else declare the function in the class as

friend std::ostream& operator<<(std::ostream& stream, const Cat& cat);

So that the private members are visible to the function.

Share this post


Link to post
Share on other sites
I figured it out...

Here I have my class...

class WackyCat
{
data and functions and things, oh my!
}

Then, I do this:

ostream& operator<<(ostream& os, WackyCat &uWCat)
{
os << uWCat.whatevermemberfunction() << " ";
os << uWCat.whateverelsememberfunction() << " ";
return os;
}

It works pretty good! Anyone see any problems with it?

Share this post


Link to post
Share on other sites
Could also add some localization support, and using a virtual print member function could help remove the get functions from the class interface, and also allows you to output to the stream polymorphically to a greater extent than you can with your current implementation.

Share this post


Link to post
Share on other sites
//////////////////////////////////////////////////////
Looks OK to me. I'd make it take a const reference to the WackyCat instance though so the function isn't allowed to modify the data whilst outputting it.
//////////////////////////////////////////////////////
Sounds good, I'll add the const thingy so the data wont change.

/////////////////////////////////////////////////////
Could also add some localization support, and using a virtual print member function could help remove the get functions from the class interface, and also allows you to output to the stream polymorphically to a greater extent than you can with your current implementation.
//////////////////////////////////////////////////////
I haven't the faintest idea what your talking about, but thanks for helping... (I'm a beginner).

Share this post


Link to post
Share on other sites
What the other guy is saying with the virtual print member functions is something like:

class WackyCat {
public:
virtual ostream& printTo(ostream& os) {
// do stuff for printing a 'normal' WackyCat:
os << foo() << " " << bar() << " ";
// and you can print data here too, even private stuff.
// When I was in university, they taught me to handle
// this by making ostream a friend class so that it could
// access the needed public data directly. IMHO that's an
// awful way of doing things though.
return os;
}
}

class WackierCat: public WackyCat {
public:
ostream& printTo(ostream& os) {
// print different stuff because this cat is wackier!
os << bar() << " " << baz() << " ";
return os;
}
}

ostream& operator<<(ostream& os, const WackyCat &uWCat) {
uWCat.printTo(os);
// at runtime, this will check which kind of WackyCat you have
// and call the appropriate printTo() method.
return os;
}



In Java, the paradigm is that every Object can provide a toString() method, which is called when needed for outputting. I suppose you could do something like this in C++, by implementing "operator std::string()", but then you get into some of C++'s weirder implicit-conversion idiosyncrasies eventually, and also will probably need a strstream when you write your implementation (so that it's kind of self-defeating).

Share this post


Link to post
Share on other sites

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this