lundi 24 juin 2019

Ideas on getting rid of boiler plate code

My problem is very specific. I have the following requirement, I need to set member variables that exist in child class from parent class, for several reasons. My plan is to pass a function pointer of the setter method (which exist in child class), that takes string as argument, to the parent class at construction. The parent class defines a public method that takes member name and value string as argument and invokes the function pointer of the member with value string. The parent class can exist in a dll or lib and have no access to any conversion or factory methods, so the setter method have to be defined in child class.

Since the parent can be a base class for other classes, i wrote some macros shown as below:

#define DEFINE_VAL(Type, memberName) \
        private: \
            Type memberName; \
            void set##memberName(std::string const& val) { \
                memberName = convert_to_val(val); /* this will be a call to factory which converts string to value type*/\
            }; \

#define INIT_VAL(memberName) \
            { memberName, \
            [&](std::string const& val) { set##memberName(val); }}

Parent and child classes are as below:

// parent.h probably in dll
class parent
{
public:
    parent(std::map<std::string, std::function<void(std::string const&)>>& m)
        : m(m)
    { }
        ... 
private:
    std::map<std::string, std::function<void(std::string const&)>> m;
};

// child.h
class child : public parent
{
public:
    child() : parent({ INIT_VAL(iVal), ... })
    { }
private:
    DEFINE_VAL(int, iVal);
        ...
};


The child class can have many variables defined and its a bit annoying to first use DEFINE_VAL macro and then pass each variable's setter method with INIT_VAL macro. Can this be done in macro (probably in DEFINE_VAL)? or any ideas on automatic registration of member name and function pointer to parent class?

I would also appreciate any alternative ideas on accomplishing my requirement.

Aucun commentaire:

Enregistrer un commentaire