I recently came across classes that use a configuration object instead of the usual setter methods for configuration. A small example:
class A {
int a, b;
public:
A(const AConfiguration& conf) { a = conf.a; b = conf.b; }
};
struct AConfiguration { int a, b; };
The upsides:
- You can extend your object and easily guarantee reasonable default values for new values without your users ever needing to know about it.
- You can check a configuration for consistency (e.g. your class only allows some combinations of values)
- You save a lot of code by ommiting the setters.
- You get a default constructor for specifying a default constructor for your Configuration struct and use
A(const AConfiguration& conf = AConfiguration()).
The downside(s):
- You need to know the configuration at construction time and can’t change it later on.
Are there more downsides to this that I’m missing? If there aren’t: Why isn’t this used more frequently?
Whether you pass the data individually or per struct is a question of style and needs to be decided on a case-by-case basis.
The important question is this: Is the object is ready and usable after construction and does the compiler enforce that you pass all necessary data to the constructor or do you have to remember to call a bunch of setters after construction who’s number might increase at any time without the compiler giving you any hint that you need to adapt your code. So whether this is
or
doesn’t matter all that much. (There’s a number of parameters where everyone would prefer the former, but which number this is – and whether such a class is well designed – is debatable.) However, whether I can use the object like this
or have to do this
before I can use the object, does make a huge difference. Especially so, when someone comes along and adds another data field to
A.