14.9  Конструктор по умолчанию

Конструктором по умолчанию (в англ. языке используется термин default constructor) является конструктор, который может вызываться без аргументов.

Если в исходном коде класса пользователь не создал ни одного конструктора, то компилятор сам создает конструктор по умолчанию неявным способом. Однако если пользователь создал хотя бы один конструктор в классе, компилятор создавать конструктор по умолчанию не будет. Рассмотрим пример класса Stack с конструктором по умолчанию, созданным пользователем:

class Stack

{

char * s; 

int max_len;

int top;

public:

Stack();  // Конструктор по умолчанию

// …

};

inline Stack :: Stack()

{                   

s = "    ";  

max_len = 0;

top = 0;

}

Или, с использованием списка инициализации можно записать:

inline Stack :: Stack() : s("    "), max_len(0),  top(0) { }

Как видно из примера, закрытые переменные-члены проинициализированы по умолчанию нулем.

В языке C++, если поле экземпляра класса явным образом не инициализировано в списке, то вызывается конструктор по умолчанию для инициализации этого поля. Если такой тип не имеет конструктора по умолчанию, то это считается ошибкой.

В конструкторах удобно задавать значения параметров по умол­чанию. Это упрощает использование конструкторов. Значение па­раметров по умолчанию можно указать или при объявлении конст­руктора, или в его определении. Все параметры по умолчанию дол­жны стоять последними. Например, можно указать размер стека по умолчанию для кон­структора класса Stack:

Stack :: Stack(int size = 512)

{

  s = new char [size];

  max_len = size;

  top = 0;

}   

Если для инициализации объектов класса Stack планируется ис­пользование конструктора по умолчанию, то в определении класса Stack конструктор по умолчанию должен быть только один: или Stack(), или Stack (int size =512).

Ничего особенного в определении конструктора как функции нет. Отличие от остальных член-функций заключается только в том, что конструктор может вызываться неявно для каждого объекта класса, определенного пользователем, и не имеет явно указанного возвра­щаемого значения.

Предположим, что в определении класса Stack содержится кон­структор по умолчанию Stack(). Конструктор по умолчанию вызы­вается, например, при объявлении объекта:

Stack st;                 // Вызывается конструктор Stack()

Stack st = Stack(); // Вызывается конструктор Stack()

Stack st();              // Неправильно

Форма вызова в последнем примере неправильна, поскольку ис­пользование st() равносильно объявлению прототипа функции st, у которой нет аргументов и которая возвращает объект класса Stack.

Синтаксис объявления конструктора не содержит типа возвращаемого значения. Фактически конструктор значение возвращает, но неявно. Конструктор всегда возвращает значение указателя this на текущий объект, и нет необходимости объявлять это явно. С каждым объектом связан неявный указатель this. Он передается как неявный аргумент при вызове член-функции. Мож­но определить, для какого объекта вызывается конструктор: или для создаваемого посредством объявления, или создаваемого через операцию new. В случае создания объекта операцией new, указатель this при входе в функцию-конструктор равен нулю, в против­ном случае – указывает на уже созданный объект.

На конструктор, как и на любую другую член-функцию, рас­пространяются правила видимости private и public. Если конструк­тор описан в части private, воспользоваться им можно только при создании объекта член-функциями класса. Например:

class Stack

{

private:

Stack(int);

// …

 };  

Stack s1(200); // Неправильно (Stack(int) "не виден" и им нельзя воспользоваться)

Stack s2;         // Правильно (объект создается без использования конструктора)

Поскольку конструктор Stack (int) описан в части private, проинициализировать объект при объявлении в программе нельзя: конструктор " не виден ".

В классе может быть определено несколько конструкторов, ко­торые заданы в различных частях private и public. В этом случае проинициализировать объект можно только "видимыми" в данный момент конструкторами. Для член-функций класса видны все кон­структоры этого класса.