1

Let's say I have a class as follows

class Rectangle{
    public:
    int height;
    int width;

};

How can I print out a list of the members of this class without manually saying cout<<a.height or something like that. In other words, without knowing what members a different class has, is there a way for me to print out the members given a new class?

billz
  • 44,644
  • 9
  • 83
  • 100
bachkoi32
  • 1,426
  • 4
  • 20
  • 31
  • 2
    C++ does not have any built-in introspection facilities. Can you tell us a bit more about what you're trying to achieve and why? – Cody Gray - on strike May 27 '13 at 12:14
  • 2
    You can't do this that easy. – Pixelchemist May 27 '13 at 12:14
  • 1
    I guess some of your friend must have told you that you can do that in Java.. (which is correct... there is Reflection API in Java) but in C++ there is no such facility. You can read this previous post http://stackoverflow.com/questions/41453/how-can-i-add-reflection-to-a-c-application which is an attempt in that direction. – AurA May 27 '13 at 12:17
  • If you want to generate documentation on what members a class has you can use Doxygen (looks kind of like Javadoc). – Simon May 27 '13 at 12:17

2 Answers2

8

It seems you want to overload the operator<< for a std::ostream object. I assume you're wanting to do something like so:

Rectangle rect;
std::cout << rect;

Instead of:

Rectangle rect;
std::cout << "Width: " << rect.width << '\n';
std::cout << "Height: " << rect.width;

The overloaded function (remember overloading operators is overloading functions, except with a specific signature) must have the following signature:

std::ostream& operator<<(std::ostream&, const Type& type);

Where std::ostream is an ostream object (such as a file), in this case it will be std::cout, and Type is the type you wish to overload it for, which will be Rectangle in your case. The 2nd parameter is a const reference because printing something out doesn't usually require you to modify the object, unless I am mistaken the 2nd parameter does not have to be a const object, but it is recommended.

It must return a std::ostream in order for the following to be possible:

std::cout << "Hello " << " operator<< is returning me " << " cout so I " << " can continue to do this\n";

This is how you do so in your case:

class Rectangle{
  public:
    int height;
    int width;
};

// the following usually goes in an implementation file (i.e. .cpp file), 
// with a prototype in a header file, as any other function
std::ostream& operator<<(std::ostream& output, const Rectangle& rect) 
{
    return output << "width: " << rect.width <<< "\nheight: " << rect.height;
}

If you have private data in your Rectangle class, you may want to make the overloaded function a friend function. I usually do this even if I don't access the private data, just for readability purposes, it's up to you really.

i.e.

class Rectangle{
  public:
    int height;
    int width;

    // friend function
    friend std::ostream& operator<<(std::ostream& output, const Rectangle& rect);
};


std::ostream& operator<<(std::ostream& output, const Rectangle& rect)
{
    return output << "width: " << rect.width <<< " height: " << rect.height;
}
miguel.martin
  • 1,626
  • 1
  • 12
  • 27
  • Thanks for this, but this wouldn't work in a case where someone else puts in a new class and expects to print out the list of members without overloading the << operator – bachkoi32 May 27 '13 at 12:35
  • 1
    @sanke93 That's why you overload the << operator for that class. If the << operator is not provided for you via someone else's code and you would like to print in this manner, then you would have to provide it yourself. There is no general way to do this in C++, even if there were it would be restricting the programmer, as printing different types of objects may not even want to print all their member variables (e.g. printing a calculated value for an object instead of a variable). As in OOP languages, data is usually always hidden from the client, and accessed via gettes/setters. – miguel.martin May 27 '13 at 12:42
0

As others have pointed out, C++ provides no means to do this automatically.

Good coding practice in C++ is to provide the declaration of a class and its members, as well-commented and documented as possible, in a header file named identically to the class declared within.

DevSolar
  • 67,862
  • 21
  • 134
  • 209