Home > Mobile >  auto-generate method calls to every member object of a class
auto-generate method calls to every member object of a class

Time:12-24

I would like to be able to 'forward' a member function call of a class to every member variable of the class:

class MyObject {
    X_Behavior v1;
    X_Behavior v2;
    ...
    Y_Behavior v10;
    Z_Behavior v11;
    ...
public:
    void clear() { v1.clear(); v2.clear(); ... v10.clear(); v11.clear(); }
    void hide()  { v1.hide();  v2.hide();  ... v10.hide();  v11.hide();  }
    void show()  { v1.show();  v2.show();  ... v10.show();  v11.show();  }
};

All these functions are implemented in every component class, according to the expected 'behavior'. e.g.

class X_Behavior {
public:
    void clear(); 
    void hide();
    void show();
    ...
};

Manual copying if these iterations

    void clear() { v1.clear(); v2.clear(); ... v10.clear(); v11.clear(); }
    void hide()  { v1.hide();  v2.hide();  ... v10.hide();  v11.hide();  }
    void show()  { v1.show();  v2.show();  ... v10.show();  v11.show();  }
    ... more similar members here ...

is hard to maintain and review.

There are many classes like MyObject, each with many member variables. Many developers edit them. Also, you cannot tell whether an ommitted call or a mixed order was intentional or not.

Can you propose a compiler-generated construct that allows me to implement these functions once and not touch them again?

void MyObject::clear() {  /* call clear() for every (_Behavior) member of this class */ }
void MyObject::hide()  {  /* call hide()  for every (_Behavior) member of this class */ }
void MyObject::show()  {  /* call show()  for every (_Behavior) member of this class */ }
  • I do not wish to increase the size of MyObject.

  • The *_Behavior classes should stay as they are. Not to be tied to a base class.

  • I want to do this without employing the Preprocessor. Can you propose a C 11/17/20 solution for this?

  • Ideally, I would like to see if this could be done with minimal code, just like the compiler generated default implementations for constructor, copy constructor, assignments, destructor.

CodePudding user response:

I think that your best option is to create a base class for the Behavior classes. If you really want to avoid that, you could store them as unions (or std::variants, but it would make the code needlessly more complicated and less readable.

CodePudding user response:

A macro might help:

class MyObject
{
    X_Behavior v1;
    // ...
    Z_Behavior v11;
#define CALL_ON_ALL(F) do { v1.F(); /* ... */ v11.F(); } while(0)

public:
    void clear() { CALL_ON_ALL(clear); }
    void hide()  { CALL_ON_ALL(hide);  }
    void show()  { CALL_ON_ALL(show);  }

#undef CALL_ON_ALL
};
  •  Tags:  
  • c
  • Related