Множественные конструкторы

До сих пор в наших классах мы разрабатывали как default-, так и nondefault-конструкторы. В результате предыдущих рассуждений вы можете предположить, что они являются взаимоисключающими, поскольку все классы имели одиночный конструктор. C++ "признает" нашу потребность в разнообразии способов инициализации объекта и позволяет определять множественные конструкторы в одном и том же классе. Компилятор использует перегрузку функции для выбора правильной формы конструктора, когда мы создаем объект. Концепция перегрузки функции и ее правила обсуждаются в главе 6. Multiple-конструкторы добавляют большие возможности классу. Особый тип multiple-конструктора, называемый конструктором копирования (copy constructor), используется со многими классами, содержащими динамические данные-члены. Конструктор копирования описывается в главе 8.

           
 
Месяц 1£m£12
 
День 1£m£31
 
Год 1900£m£1999

 


Класс 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 показывает способ эффективного хранения треугольной матрицы в виде одномерного массива.