Множественные конструкторы
До сих пор в наших классах мы разрабатывали как default-, так и nondefault-конструкторы. В результате предыдущих рассуждений вы можете предположить, что они являются взаимоисключающими, поскольку все классы имели одиночный конструктор. C++ "признает" нашу потребность в разнообразии способов инициализации объекта и позволяет определять множественные конструкторы в одном и том же классе. Компилятор использует перегрузку функции для выбора правильной формы конструктора, когда мы создаем объект. Концепция перегрузки функции и ее правила обсуждаются в главе 6. Multiple-конструкторы добавляют большие возможности классу. Особый тип multiple-конструктора, называемый конструктором копирования (copy constructor), используется со многими классами, содержащими динамические данные-члены. Конструктор копирования описывается в главе 8.
|
|
|
Класс Date иллюстрирует использование multiple конструкторов. Этот класс имеет три данных-члена, которые обозначают месяц, день и год в дате.
Один конструктор имеет три параметра, соответствующие трем данным-членам. Действием конструктора является инициализация этих переменных. Второй конструктор позволяет клиенту объявлять дату как строку в форме "mm/dd/yy", читает эту строку и преобразует пары символов "mm" в месяц, "dd" в день и "уу" в год. Для каждого конструктора мы подразумеваем, что параметр, задающий год — это значение из двух цифр в диапазоне 00-99. Фактический год сохраняется добавлением 1900 к начальному значению:
year = 1900 + уу
Класс Date имеет метод, который выводит на экран полную дату с названием месяца, дня и значением года. Например, первый день в двадцатом веке был 1 января 1900
Спецификация класса Date
ОБЪЯВЛЕНИЕ
#include <string.h>
#include <strstream.h>
class Date
{
private:
// закрытые члены, которые определяют дату
int month, day, year;
public:
// конструкторы, дата по умолчанию — Январь 1, 1900
Date (int m = 1, int d = 1, int у = 0);
Date (char *dstr);
// вывод данных в формате "месяц день, год"
void PrintDate (void);
};
ОПИСАНИЕ
Для построения Date-объектов используются два конструктора, отличающиеся параметрами. Компилятор выбирает конкретный конструктор во время создания Date-объекта. Следующие примеры демонстрируют создание объектов.
ПРИМЕРЫ
Date dayl(6, б, 44) ;
Date day2;
date day3("12/31/99");
// 6 июня 1944
// значение по умолчанию для 1 января 1990
// 31 декабря 1999
Реализация класса Date
Сердцевиной класса Date являются два его конструктора, которые определяют дату, передавая значения месяца, дня и года или строки "mm/dd/yy".
Первый конструктор имеет три параметра со значениями по умолчанию, соответствующими 1 января 1900 года. Со значениями по умолчанию конструктор квалифицируется как конструктор умолчания:
// конструктор. day и year задаются как целые mm dd yy
Date::Date (int m, int d, int y) : month(m), day(d)
{
year = 1900 + у; // у - год в 20-м столетии
};
Альтернативная форма конструктора принимает строковый параметр. Строка имеет форму "mm/dd/yy". Для преобразования пар данных мы используем ввод на базе массива, который преобразует символьные пары "mm" в целое значение месяца и так далее. Копируем строку параметра в массив inputBuffer и затем читаем символы в таком порядке:
Month-ch-day-ch-year Ввод ch удаляет два разделителя "/" из строки ввода.
// конструктор
// month, day и year задаются в виде строки "mm/dd/yy"
Date::Date {char *dstr)
{
char inputBuffer[16];
char ch;
// копирование в inputBuffer
strcpy(inputBuffer,dstr);
istrstream input(inputBuffer, sizeof(inputBuffer));
// чтение данных из входного потока ch используется в
// качестве символа '/'
input >> month >> ch >> day >> ch >> year;
year += 1900;
};
При выводе метод Print дает текст полной даты, включающий название месяца, дня и год. Массив months содержит пустую строку (индекс 0) и 12 названий для календарных месяцев. Значение месяца используется как индекс в массиве для печати названия месяца.
// печать даты с полным названием месяца
void Date::PrintDate (void)
{
// статический массив с названиями месяцев
static char *Months[] = {"", "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"};
cout << Months [month] << " " << day << ", "<< year;
};
Программа 4. Дата двадцатого века
Тестовая прграмма использует конструкторы для установки демонстрационных объектов. Получаемые в результате данные печатаются. Класс Date содержится в файле "date.h".
#include <iostream.h>
#include "date.h"
// включение класса Date
void main (void)
//Date-объекты с целыми, умалчиваемыми и строчными параметрами
Date dayl(6,6,44);// Июнь 6, 1944
Date day2;// Январь 1, 1900
Date day3 ("12/31/99") ; // Декабрь 31, 1999
cout << "День Д во Второй Мировой войне — ";
dayl.PrintDate() ;
cout << endl;
cout << "Первый день 20-ого века — ";
day2.PrintDate( ) ;
cout << endl;
ccut << "Последний день 20-ого века — ";
day3.PrintDate( ) ;
cout << endl;
}
/* <Выполнение программы 3.4>
День Д во Второй Мировой войне — Июнь 6, 1944
Первый день 20-ого века — Январь 1, 1900
Последний день 20-ого века — Декабрь 31, 1999 */
6. Практическое применение: Треугольные матрицы
Двумерный массив, часто называемый матрицей (matrix), предоставляет важную для математики структуру данных. В этом разделе мы исследуем квадратные матрицы (square matrices — матрицы с одинаковым числом строк и столбцов), чьи элементы данных являются действительными числами. Мы разрабатываем класс TriMat, определяющий верхние треугольные матрицы (upper triangular matrices), в которых все элементы, находящиеся ниже диагонали, имеют нулевые значения.
(пример треугольной матрицы)
В математических терминах, Аi,j=0 для j<i. Верхний треугольник определяется элементами Аi,j для j³i. Эти матрицы имеют важные алгебраическиесвойства и используются для решения систем уравнений. Реализация операций верхней треугольной матрицы в классе TriMat показывает способ эффективного хранения треугольной матрицы в виде одномерного массива.