Find the list of member variables of a class and their types?

13,804

Solution 1

There is no reflection in C++, so you'll need an external library to do this. The creators of C++ didn't implement this feature because it implies a performance penalty, and performance is one of C++'s main goals.

Solution 2

I always have to remember that if I add another variable int k to the class, I'll also have to add it in the initialization list k(soc.k) and sometimes in the destructor too.

Yep, you do.

I've had to add/remove member variables so many times and it's really annoying to forget about the copying in the initialization list and finding the omission much much later while debugging.

Yes, it is.

Therefore, I wanted to know if there's a syntax/logic through which I can find out the list of member variables of a class and their types, so that I can maybe iterate through them and decide which of them need to be copied in the copy ctor and which of them need to be deep copied?

No, there isn't.

I don't see why the creators of C++ couldn't have included such a facility, since except for virtual members, the memory locations of variables would be contiguous and their types are known too. Even if they were extern or virtual, the type and size would be known at runtime. So shouldn't it be possible?

Yes, ideally.

C++ isn't really "that sort of a language", but it is a bit of a pain.

Solution 3

please consult http://yosefk.com/c++fqa/defective.html#defect-6

for a point of view on the topic.

and as an answer, basically you can't do it.

Solution 4

Yes well it do not answer your question but to solve your problem what I did in my code is to use a struct to hold the members that can be copied automatically so that I don't have to worry about them.

class A
{
 public:
  SomeOtherClass* s;

  class Members
  {
    int i;
    int j;
  };

  Members m;

  A() {}
  A(const A& soc): s(soc.s->Clone()), m(soc.m) {}

  void f() {
    m.j;//use j
  }
};

But generally I prefer to use deep_copy pointers so that I don't even need that trick (pointer are also copied automatically, when I can).

I posted about it some time ago : https://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-utility/1609496#1609496.

I'm not sure this will solve your problem with destructor (maybe the deep_copy pointer will).

If you're interested, I also suggest to check the posts that were talking about memberspace here on stackoverflow, which was basically using the same kind of trick for other means if I remember correctly.

Share:
13,804
Nav
Author by

Nav

Updated on June 19, 2022

Comments

  • Nav
    Nav almost 2 years

    I haven't ever heard it's possible, but asking with the hope that it might.
    For a class with many more member variables than this:

    class A
    {
     public:
      SomeOtherClass* s;
      int i;
      int j;
      A() {}
      A(const A& soc): s(soc.s->Clone()), i(soc.i), j(soc.j) {}
    };
    

    I always have to remember that if I add another variable int k to the class, I'll also have to add it in the initialization list k(soc.k) and sometimes in the destructor too. I've had to add/remove member variables so many times and it's really annoying to forget about the copying in the initialization list and finding the omission much much later while debugging.

    Therefore, I wanted to know if there's a syntax/logic through which I can find out the list of member variables of a class and their types, so that I can maybe iterate through them and decide which of them need to be copied in the copy ctor and which of them need to be deep copied?

    I don't see why the creators of C++ couldn't have included such a facility, since except for virtual members, the memory locations of variables would be contiguous and their types are known too. Even if they were extern or virtual, the type and size would be known at runtime. So shouldn't it be possible?

  • Nav
    Nav almost 13 years
    Is there any external library? What kind of performance penalty (apart from not having the luxury of using the initialization list)? But having the choice of using the initialization list is what'd make C++ powerful. I don't see any other reason for omitting it for performance reasons.
  • dario_ramos
    dario_ramos almost 13 years
    According to Google, yes (XCppRefl tops the search results). Never tried any of those, though. You might want to ask a separate question about which library is best.
  • Nav
    Nav almost 13 years
    Okay, which library is best :)
  • dario_ramos
    dario_ramos almost 13 years
    I have no idea :P You should ask in a separate, new question. And some advice: I think using reflection for this is overkill. As they said in another question, code reviews and unit testing are a better option for catching this kind of bugs
  • dario_ramos
    dario_ramos almost 13 years
    About the performance penalty: to implement reflection, you need to store metadata about every class somewhere, and that's the main reason. Okay, it could be optional, and the initializer list as well, but I trust Bjarne on this, he knows his stuff
  • Nav
    Nav almost 13 years
    Was surprised to see that someone downvoted an answer that I upvoted. Whoever did this, why did you do it? I think Ali had given a correct link to the concept of reflection.
  • Hayri Uğur Koltuk
    Hayri Uğur Koltuk over 11 years
    i also thought it's a constructive answer, since link contains a clear answer to the question. Downvoter, please kindly write why you did it, then I'll fix myself if I'm mistaken.
  • Pellekrino
    Pellekrino over 5 years
    Interesting link, but kinda outdated : it is from 2009, before the C++11 upgrade. (haven't downvoted ;))