Avoiding duplicated code in class constructors. C++

Question:

class Boo
{
public:
    Boo()
    {
        Сделать X
    }
    Boo(int value)
    {
        Сделать Х
        СделатЬ У
    }
};

For example, I need to do something in the constructors. And in these two constructors there is a duplicated code. As far as I know there are two ways to avoid this.

// 1 вариант
class Boo
{
public:
    Boo()
    {
        Сделать X
    }
    Boo(int value):Boo()
    {
        СделатЬ У
    }
};
// 2 Вариант

class Boo
{
public:
    Boo()
    {
        doX();
    }
    Boo(int value)
    {
        doX();
        Сделать У;
    }

    void doX()
    {
        Делает X;
    }
};

Which one is better? Why ? Or maybe there is something better?

Answer:

If the "actions" you are talking about should be performed exactly in the body of the constructor (between {} ), then there is no fundamental difference between these approaches. The second option only adds an extra entity – an additional class method. If you close your eyes to it, then it doesn't matter how you do it.

But here it should be noted that in the constructor, first of all, we are interested in eliminating repetitions in the initialization list , i.e. specifically for

class Boo
{
public:
    Boo(x, y) : 
        хитро_инициализировать_A(x, y), 
        хитро_инициализировать_B(x, y)
      {}
    Boo() : 
        хитро_инициализировать_A(3, 42),  
        хитро_инициализировать_B(3, 42)
      {}
};

We used to have to pervert through

class Boo
{
public:
    Boo(x, y) :
      // "Ложная" инициализация, возможно неявная
      инициализировать_A_какой-то-хренью, 
      инициализировать_B_какой-то-хренью
    { 
      do(x, y);
    }

    Boo() : 
      // "Ложная" инициализация, возможно неявная
      инициализировать_A_какой-то-хренью, 
      инициализировать_B_какой-то-хренью
    {
      do(3, 42);
    }

    void do(x, y)
    { // Вторая, "настоящая" инициализация 
      хитро_переинициализировать_A_по-новому(x, y);
      хитро_переинициализировать_B_по-новому(x, y);
    }
};

Those. in this variant, A and B will generally first go through some "default" initialization, and then through an additional "pre-initialization" (or "re-initialization") already in the function. This is irrational. This annoying phenomenon is known as the double initialization problem . And besides, this approach cannot be applied at all to fields that do not allow default initialization or reinitialization (reference fields, constant fields, etc.)

This is where we come to the rescue

     ...
     Boo() : Boo(3, 42)
      {}
     ...

This variant was introduced into the language "relatively recently" in the first place in order to solve the above problem of double initialization. The constructor delegating approach is free from this shortcoming. It is the initialization that is performed and it is performed exactly once.

Scroll to Top