user16647
user16647

Reputation: 165

Ways to print user-defined objects

I'm curious about the ways of printing user-defined objects. By that, I mean printing objects to an output stream. Is it possible to have a stream class provide methods that could print all kinds of objects, similar to how the Object type in Java can provide toString() methods to all derived classes? I imagine that one issue is the lack of classes being able to derive from the stream class, since with the Object example in Java, all classes are implicitly subclasses of Object. Are there others?

Upvotes: 0

Views: 1064

Answers (6)

Mooing Duck
Mooing Duck

Reputation: 66922

Extending Pubby's answer somewhat, you can make the operator<< function work for all stream types with a minor modification. Also shown here is how to stream in.

class foo {
  //output works for all basic_ostreams
  template<class e, class t>
  friend std::basic_ostream<e,t>& 
        operator<<(std::basic_ostream<e,t>& os, const foo& f) 
  {
    return os << f.x;
  }
  //input is very similar.  Here's the differences:
  // istream instead of ostream
  // >> instead of <<
  // foo is not const
  template<class e, class t>
  friend std::basic_istream<e,t>& 
        operator>>(std::basic_istream<e,t>& is, foo& f) 
  {
    return os >> f.x;
  }
  public:
    // ...
  private:
    int x;
};

int main() {
     foo myfoo;
     std::cout << "enter foo: ";
     std::cin >> myfoo;
     std::cout << "myfoo is " << myfoo << '\n';
     std::wcout << L"myfoo is " << myfoo << L'\n';
}

Upvotes: 0

Pubby
Pubby

Reputation: 53037

Since this is tagged C++, here's a C++ answer:

Just overload std::ostream& operator<<(std::ostream&, const foo& f) doing something like this:

class foo {
  friend std::ostream& operator<<(std::ostream& os, const foo& f) {
    return os << f.x;
  }
  public:
    // ...
  private:
    int x;
};

int main() {
     foo myfoo;
     std::cout << "myfoo is " << myfoo << '\n';
}

There are much better guides out there on how to do this.

Upvotes: 2

Michael
Michael

Reputation: 2634

You want to look at 2 things:

  1. The Java Class object
  2. The concept of Java reflections

Basically the combination of both allows you to introspect into any given object so its reasonably easy to come up with a generic method to print objects like you wanted. I.e.

String myClassName = "com.my.class.NameHere";
Class c = Class.forName(myClassName);
Method m[] = c.getDeclaredMethods();
for(Method method: m)
  System.out.println(method.toString());

Upvotes: 0

Snicolas
Snicolas

Reputation: 38168

@Aidanc answer could work. All depends on what you want to do. If you want to print objects fields to the console, that's the solution.

But if you want to send them through a network for instance, without any human reading the stream, use an ObjectOutputStream. It can write (and ObjectInputstream can read) objects from and to a stream, whatever it is, either a socket or a file.

Almost all Objects can be sent that way, those who implement Serializable are themselves in charge of their serialisation (converting an object to sequence of 0s and 1s) and for other, you can still use the Externalizable Api.

Upvotes: 0

ControlAltDel
ControlAltDel

Reputation: 35011

It is not possible to stream all kinds of Objects. For instance, how would you stream a Thread? What would this mean?

Upvotes: 0

Aidanc
Aidanc

Reputation: 7011

Override the toString() function and call that. I don't see how you could have a god class that simply prints all kinds of objects.

Upvotes: 1

Related Questions