views:

202

answers:

7

What's the best way to output the public contents of an object to a human-readable file? I'm looking for a way to do this that would not require me to know of all the members of the class, but rather use the compiler to tell me what members exist, and what their names are. There have to be macros or something like that, right?

Contrived example:

class Container
{
public:
    Container::Container() {/*initialize members*/};
    int stuff; 
    int otherStuff;
};
Container myCollection;

I would like to be able to do something to see output along the lines of "myCollection: stuff = value, otherStuff = value". But then if another member is added to Container,

class Container
{
public:
    Container::Container() {/*initialize members*/};
    int stuff;
    string evenMoreStuff;
    int otherStuff;
};
Container myCollection;

This time, the output of this snapshot would be "myCollection: stuff = value, evenMoreStuff=value, otherStuff = value"

Is there a macro that would help me accomplish this? Is this even possible? (Also, I can't modify the Container class.) Another note: I'm most interested about a potential macros in VS, but other solutions are welcome too.

+1  A: 

Take a look at this library .

arul
+1  A: 

What you need is object serialization or object marshalling. A recurrent thema in stackoverflow.

Fernando Miguélez
+2  A: 

What you're looking for is "reflection".

I found two promising links with a Google search for "C++ reflection":

http://www.garret.ru/cppreflection/docs/reflect.html

http://seal-reflex.web.cern.ch/seal-reflex/index.html

Peter Crabtree
A: 

There's unfortunately no macro that can do this for you. What you're looking for is a reflective type library. These can vary from fairly simple to home-rolled monstrosities that have no place in a work environment.

There's no real simple way of doing this, and though you may be tempted to simply dump the memory at an address like so:

char *buffer = new char[sizeof(Container)];
memcpy(buffer, containerInstance, sizeof(Container));

I'd really suggest against it unless all you have are simple types.

If you want something really simple but not complete, I'd suggest writing your own printOn(ostream &) member method.

ReaperUnreal
+1  A: 

I'd highly recommend taking a look at Google's Protocol Buffers.

Adam Rosenfield
+2  A: 

Boost has a serialization library that can serialize into text files. You will, however, not be able to get around with now knowing what members the class contains. You would need reflection, which C++ does not have.

Johannes Schaub - litb
A: 

XDR is one way to do this in a platform independent way.

Iulian Şerbănoiu