Хотя конструкторы и предназначены для решения особо важных задач, они мало чем отличаются от обычных функций и могут быть перегружены. Как было показано ранее, для перегрузки конструктора класса достаточно просто объявить различные его формы. Как будет показано далее, во многих случаях перегрузка конструкторов позволяет добиться определенных преимуществ.
Начнем с примера. В следующей программе объявляется класс timer, действующий как таймер обратного отсчета. При создании объекта типа timer ему присваивается начальное значение времени. В результате вызова функции run() таймер начинает отсчет в сторону уменьшающихся значений, пока не достигнет значения 0, после чего зазвонит звонок. В данном примере конструктор перегружен для того, чтобы можно было указывать время в секундах с помощью целого числа или строки, или в минутах и секундах, если указываются два целых числа.
Эта программа использует библиотечную функцию clock(), возвращающую число тиков, прошедших с момента запуска программы. Поделив это значение на макрос CLK_TCK, получаем значение в секундах. Прототипы для clock() и CLK_TCK содержатся в заголовочном файле time.h.
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
class timer {
int seconds;
public:
/ / секунды задаются строкой
timer(char *t) { seconds = atoi(t); }
// секунды задаются целым числом
timer (int t) { seconds = t; }
// время задается в минутах и секундах
timer (int min, int sec) { seconds = min*60 + sec; }
void run();
};
void timer::run()
{
clock_t t1, t2;
t1 = t2 = clock () /CLK_TCK;
while (seconds) {
if (t1/CLK_TCK+1 <= (t2=clock())/CLK_TCK) {
seconds--;
t1 = t2;
}
}
cout << "\a"; // звонок
}
int main()
{
timer a(10), b(20), c(1, 10);
a.run (); // отсчитать 10 секунд
b.run (); // отсчитать 20 секунд
c.run (); // отсчитать 1 минуту, 10 секунд
return 0;
}
Как можно видеть, при создании объектов a, b и с внутри функции main() они получают начальное значение с использованием трех различных методов, поддерживаемых перегруженными конструкторами. Каждый из них позволяет провести инициализацию для соответствующих данных.
В приведенной выше программе не видно больших достоинств перегрузки конструкторов, потому что можно просто воспользоваться только одним из способов инициализации. Однако если создается библиотека классов, которую будет использовать кто-то кроме ее автора, то, возможно, имеет смысл снабдить ее конструкторами для всех наиболее употребительных форм инициализации, позволяя программисту выбрать наиболее подходящую форму для его конкретного приложения. В следующем разделе иллюстрируется еще одно из преимуществ, обеспечиваемое перегрузкой конструкторов.
ЗАМЕТКА: В языке С++ определен специальный тип перегрузки конструкторов, называемый конструктором копирования, позволяющий определить, каким именно образом копируются объекты при определенных обстоятельствах. Конструкторы копирования обсуждаются дальше на сайте www.c-cpp.ru. |