Объекты и передача информации



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

Объект как возвращаемое значение

Любой тип класса может быть возвращаемым типом функции. Например, функция SetDailyTemp принимает в качестве параметра массив чисел, представляющий показания температуры, извлекает максимальное и минимальное показания из списка и возвращает объект Temperature с этими крайними значениями.

Temperature SetDailyTemp(float reading[], int n)

{

//создание t с 1-ми значениями high и low

Temperature t(reading[0], reading[0]);

//обновление high или low, если необходимо

for (int i=1; i<n; i++)

t.UpdateTemp(reading[i]);

//возвращение t с крайними температурами этого дня

return t;

}

Массив reading содержит шесть температурных значений. Для определения высокой и низкой температур вызовите SetDailyTemp и присвойте результат объекту today. Чтобы вывести эти температуры на экран, используются методы GetHighTemp и GetLowTemp.

float reading[6]={40,90,80,60,20,50};

Temperature today=SetDailyTemp(reading,6);

cout << "Сегодняшние высокая и низкая температуры такие"

<< today.GetHighTemp() << "и"

<< today.GetLowTemp() << endl;

 

Объект как параметр функции

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

Функция TemperatureRange использует вызов по значению (call by value) параметра Т типа Temperature и возвращает разницу между самой высокой и самой низкой температурами. При выполнении этой функции вызывающий элемент копирует объект типа Temperature (фактический параметр) в Т.

float TemperatureRange(Temperature T)

{

return T.GetHighTemp()-Т.GetLowTemp();

}

Функция Celsius использует вызов по ссылке (call by reference) параметра Т типа Temperature, который, как первоначально подразумевалось, содержит значения по Фаренгейту. Функция создает объект типа Temperature, чьи самое высокое и самое низкое показания преобразуются в значения по Цельсию, и присваивает его объекту Т.

void Celsius(Temperature& T)

{

float hi, low;

//с = 5/9*(f-32)

hi = float(5)/9*(T.GetHighTemp() -32);

low = float(5)/9*(T.GetLowTemp() -32);

T = Temperature(hi, low);

}

Пример: объект Water содержит точку кипения (212° по Фаренгейту) и точку замерзания (32° по Фаренгейту) воды в качестве самого высокого и самого низкого температурных значений. Результат использования функции TemperatureRange показывает, что 180° - это диапазон для воды по шкале Фаренгейта. С помощью функции Celsius преобразуем эти температуры в значения по Цельсию и вызовем TemperatureRange, чтобы показать, что 100° - это соответствующий диапазон по шкале Цельсия,

Temperature Water(212, 32);// кипение при 212F,замерзание

                      // при 32F

cout <<"Температурный диапазон воды по шкале Фаренгейта"

<< TemperatureRange(Water) << endl;

Celsius(Water); //преобразование температуры по Фаренгейту

//в температуру по Цельсию

cout <<"Температурный диапазон воды по шкале Цельсия"

<< TemperatureRange(Water) << endl;

Массивы объектов

Тип элемента массива может включать не только встроенные типы данных, такие как int или char, но также определяемые пользователем типы класса. Результирующий массив объектов может использоваться для создания списков, таблиц и так далее. Однако, использование объектных массивов требует осторожности. Объявление массива вызывает конструктор для каждого объекта в списке. Сравните простое объявление одного объекта Rectangle и массива из 100 объектов Rectangle. В каждом объявлении конструктор вызывается для создания объекта, который задает длину и ширину. В случае массива конструктор вызывается для каждого из 100 объектов.

Rectangle pool(150,100);//создание бассейна 150х100

Rectangle room[100]; //конструктор вызывается для

//комната[0] .. [99]

Объявление объекта pool передает начальные значения конструктору. Объекты room фактически имеют начальные значения, поскольку конструктор Rectangle присваивает нулевые значения по умолчанию длине и ширине объекта:

Rectangle(float 1=0, float w=0); //параметры по умолчанию

После объявления массива длина и ширина каждого объекта room[i] имеют нулевые значения:

cout << room[25].GetLengh() //выход 0;

cout << room[25].GetWidth() //выход 0;

room[25].PutLengh(10)//установка длины комнаты[25] на 10

room[25].PutWidth(5)//установка ширины комнаты[25] на 5

Объявление массива объектов Rectangle поднимает важную проблему, касающуюся массивов и классов. Если конструктор класса Rectangle не имеет параметров по умолчанию, объявление массива room вызовет ошибку, потому что каждый массив будет требовать параметры. Объявлению потребуется список инициализаторов массива, который управляет каждым элементом в массиве. Например, для объявления массива room из 100 элементов и установки параметров длины и ширины на 0 потребуется список инициализаторов 100 объектов Rectangle. В действительности это не практикуется.

Rectangle room[100] = {Rectangle (0, 0), , . . , Rectangle(0, 0)};

Для объявления массива объектов мы предоставляем конструктору значения по умолчанию или просто создаем конструктор без параметров.

Конструктор умолчания

Конструктор умолчания (default costructor) — это конструктор, не требующий никаких параметров. Это бывает, когда конструктор не имеет параметров или когда каждый параметр имеет значение по умолчанию. В этой главе класс Rectangle содержит конструктор умолчания, тогда как класс Temperature требует параметров при объявлении объекта.

Класс Rectangle

КОНСТРУКТОР

Rectangle (float l=0, float w=0);

Конструктор содержит параметры l и w со значением по умолчанию 0. При создании массива Rectangle значения по умолчанию присваиваются каждому объекту.

Rectangle R[25];//каждый элемент имеет значение Rectangle(0,0)

Класс Temperature

КОНСТРУКТОР

Temperature(float h, float l);

Класс Temperature не содержит конструктор по умолчанию. Вместо этого, объекту должно быть дано начальное значение для высокой и низкой температуры. Объявление объектов today и week является недействительным!

Temperature today; //недействительно: отсутствуют параметры

Temperature week[7]; //Temperature не имеет конструктора по умолчанию

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

До сих пор в наших классах мы разрабатывали как 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 */


Дата добавления: 2018-10-25; просмотров: 160; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!