c++ – Passing parameters to a class

Question:

You need to create a class. It will be inherited from one of the standard classes of a fairly popular library (it doesn't matter – the ancestor may be QObject Qt or CObject from MFC ). In this case, the problem arises that a certain number of parameters must be passed to the class. They can be transmitted in three ways:

  1. in the constructor.
  2. using some additional entity in the form of the init() method with the required number of parameters.
  3. make the required number of setters and internal class variables that will be set in the process.

Each method has its pros and cons. The constructor has a serious plus, that the object is ready at once. It has no intermediate states. With the init() method, it turns out that you must remember to call it with the correct arguments once when creating an object. Further calls are undesirable (you can, for example, arrange memory leaks for yourself). On the other hand, between the call to the constructor and the init() function, the object is obtained in some incomprehensible intermediate state, when its full use is impossible. In the third case, due to the abundance of functions, you can easily get confused and forget something. In this case, all internal class variables, it turns out, must have some "default" values, otherwise, without calling these setters, the class instance will be inoperative. With constructors, it seems to me that if there is a sufficiently large number of optional input parameters, then the compiler gets a hard confusion in the head and it simply cannot assemble the code. In the end, you can try to pack all the parameters into a structure and pass a pointer to it into the constructor. But somehow it is not laconic.

For instance,

MyObject::MyObject(int a, int b, int c); // GOOD. никаких параметров по умолчанию
MyObject::MyObject(int a = 1, int b = 2; int c = 4); // GOOD
MyObject::MyObject(QObject *parent = 0, int b = 2, int c = 4); //а оно вообще соберется? и не будет ли конфликта с предыдущим вариантом?

typedef struct {int *first; QObject **parent; int *b; int *c;} arguments;
QObject *parent = 0; int b = 2; int c = 4;
arguments ar = {NULL, &parent, &b, &c}; // NULL - как бы аргумента "нет"
MyObject::MyObject(arguments &data); // нифига неизящно

In short, I ask for advice on how best to do it. It is clear that there are no universal cases, but some recommendations should exist.

Answer:

About three ways. 2 (with init method) is sad. Initialization must be inside a constructor. Although, some "meters", inventing Tizen (a new OS for phones), give out pearls . Delivers and call the RemoveAll method at the end – kind of uninit 🙂

the third way is smeared init. In fact (if the set'ers have at least some kind of logic), it will lead to difficulties in initialization – the object can be in the state of a cat of one well-known scientist ( comic in the topic ).

With constructors, it seems to me that if there is a sufficiently large number of optional input parameters, then the compiler gets a hard confusion in the head and it simply cannot assemble the code.

I think the programmer is more likely to get confused 🙂 and the compiler will either compile or not.

How would I do. For such complex classes, I would make private constructors (so that someone would not construct them). Separately, I would make a factory that, upon request, would give the constructed object (such as an assembly of patterns, a factory and a builder).

If an object can exist in ten different versions, then ten different functions are needed. Moreover, these functions can have one or two parameters, or take another class / structure as a parameter. Since the names will be different, then the compiler will not get confused, and the person. (look at an example ).

The second option is to make a class in which the constructor will accept dozens of parameters (but I vaguely believe that such a class is really needed, more on that below). And this constructor must be protected . For each specific case, a separate heir is created with a minimum of parameters in the constructor. If at some point it seems that you need to add over9000 more parameters, you need to think, maybe you need 2-3 different inheritor classes? Real life example – in windows there are many window elements – windows. and imagine if you had only one class window that did all the flavors – window, button, edit box.

Third way. The fact that so many parameters are needed suggests that it looks like a "divine class" is being designed. Therefore, such difficulties come out. Maybe from this class you can separate a piece of data + code into a separate class / classes? And then the architecture will be simplified.

Scroll to Top