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::variant
s, 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
};