В статье Конструктор и деструктор класса мы уже встречались с перегруженным конструктором в коде, но не акцентировали на этом внимание. Перегрузка конструкторов очень схожа с перегрузкой функций. Конструкторов в определяемом классе может быть несколько – по мере необходимости. Они должны иметь одинаковое имя, идентичное имени класса и обязательно должны отличаться сигнатурой.
Например: один из конструкторов не принимает параметры, второй принимает два параметра, третий принимает три параметра. Позже, во время создания объекта, параметры передаются в качестве аргументов. Так компилятор сможет определить, какой из объявленных конструкторов применить при создании объекта.
Рассмотрим пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #include <iostream> using namespace std; class _2Data { double data1; double data2; public: _2Data(); _2Data(double initData1, double initData2); void showData(); }; // конструктор класса _2Data с параметрами _2Data::_2Data(double initData1, double initData2) { data1 = initData1; data2 = initData2; cout << "\nСработал конструктор с параметрами.\n"; } // конструктор класса _2Data без параметров _2Data::_2Data() { data1 = 0; data2 = 0; cout << "\nСработал конструктор без параметров.\n"; } void _2Data::showData() // метод вывода на экран { cout << "data1 = " << data1 << endl; cout << "data2 = " << data2 << endl << endl; } int main() { setlocale(LC_ALL, "rus"); // создается объект Obj1 и вызывается конструктор // без параметров. Поля класса инициализируются 0-ми // на экран выводится "Сработал конструктор без параметров." _2Data Obj1; Obj1.showData(); // показываем данные // создается объект Obj2, вызывается конструктор c параметрами // поля класса инициализируются значениями (переданными аргументами) // на экран выводится "Сработал конструктор с параметрами." _2Data Obj2(222, 333); Obj2.showData(); // смотрим значения } |
На этом примере достаточно легко увидеть, чем вызвана необходимость перегрузки конструкторов. Основной смысл в том, чтобы дать возможность программисту выбрать наиболее подходящий способ инициализации объекта.
Тут представлен самый распространенный вариант перегрузки конструкторов. А именно конструктор с параметрами и второй без параметров. Часто, программисту бывают необходимы оба подобных конструктора, так как конструктор с параметрами удобно использовать, работая с одиночными объектами. Но он не может быть использован, например, для инициализации динамического массива объектов класса.
При каждом объявлении объекта класса надо применять соответствующий определённым конструкторам способ объявления.
Конструктор можно перегружать столько раз, сколько посчитаете нужным. Но, как бывает у большинстве случаев, желательно придерживаться золотой середины. Перегружайте его только для наиболее распространенных ситуаций.
Хочется добавить, что деструктор, в отличии от конструктора, перегружен быть не может, так как он никаких параметров не принимает.
Здесь хорошо бы добавить:
– если вы описываете класс без описания конструктора вообще, то для класса создаётся конструктор по умолчанию без параметров;
– но как только вы добавляете хотя бы один конструктор, умалчиваемый конструктор без параметров уж не создаётся (это может потом озадачить при создании объектов);
– если же всё-таки нужен и конструктор без параметров, в том числе, то его нужно описать явно.
И ещё…
Часто вместо описания нескольких конструкторов удобно создать один конструктор, но с несколькими параметрами, определёнными с умалчиваемыми значениями:
class my {
my( int first = 0, float second = 1.0, char *title = "object" ) {
// ...
}
}
...
my m1(), m2( 3 ), m3( 4, -5.5 ), m4( 5, 1.0, "new_object" );
В свое время сбивало с толку слово “перегруженный”-зачем его перегружают, почему так не любят? Потом объяснил себе, что это переЗАгруженный.