Skip to content

Latest commit

 

History

History
63 lines (50 loc) · 4.25 KB

File metadata and controls

63 lines (50 loc) · 4.25 KB

Делегирование конструкторов

До C++11 инициализация членов класса в нескольких конструкторах одного и того же класса не могли быть сосредоточены в одном месте надежным и поддерживаемым способом. Чтобы частично устранить эту проблему в существующих программах на C++, вы могли бы использовать присваивание вместо инициализации или добавить общую функцию инициализации.

С помощью функции делегирования конструкторов вы можете сконцентрировать инициализация членов класса в одном конструкторе - назовём его целевой конструктор. Делегирующие конструкторы могут вызвать целевой конструктор для выполнения инициализации. Делегирующий конструктор также может использоваться в качестве целевого конструктора одного или нескольких делегирующих конструкторов. Вы можете использовать эту функцию, чтобы сделать программы более удобочитаемыми и удобными в обслуживании.

Делегирующие конструкторы и целевые конструкторы представляют тот же интерфейс, что и другие конструкторы. Целевые конструкторы не нуждаются в специальной обработке, чтобы стать целью делегирующего конструктора. Они выбираются путем разрешения перегрузки или вычитания аргументов шаблона. После завершения выполнения целевого конструктора делегирующий конструктор получает обратно управление.

Пример #1: Делегирующий конструктор

#include <iostream>

class X 
{
public:
   const int i;

public:
   X(int x, int y) : X(x+y) { }            // Делегирующий конструктор
   X(int x, int y, int z) : X(x*y*z) {}    // Делегирующий конструктор
   X(int x) : i(x) { }                     // Целевой конструктор
};

int main(int argc, char ** argv)
{
    X var1(55, 11);
    X var2(2, 4, 6);

    std::cout << var1.i << var2.i << std::endl;

    return 0;
}

Вывод примера:

66, 48

Делегирующий конструктор может быть целевым конструктором другого делегирующего конструктора, образуя таким образом цепочку делегирования. Первый конструктор, вызываемый при построении объекта, называется основным конструктором. Конструктор не может делегировать самому себе прямо или косвенно. Компилятор может обнаружить это нарушение, если все конструкторы, участвующие в рекурсивной цепочке делегирования, определены в одной единице перевода.

Рассмотрим следующий пример: Пример #2: Рекурсивный делегирующий конструктор

class A
{
public:
  int x, y;

public:
  A():A(42) {}
  A(int x_):A() { x = x_; }
};

В примере существует бесконечно рекурсивный цикл, который конструктор A() делегирует конструктору A(int x_), а A(int x_) также делегирует A(). Компилятор выдает ошибку, указывающую на нарушение.