Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Итог_Пособие C++.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.03 Mб
Скачать

3.6 Дружественные функции и классы

Перегрузим для класса time_range операцию '<<' (вывод в поток). В качестве первого аргумента данной операции выступает объект класса std::ostream (именно такой тип имеют стандартные объекты cout и cerr).

Поскольку мы не можем добавлять новые методы в стандартный класс ostream, нам придётся перегрузить данную операцию как простую функцию , а не метод класса:

std::ostream& operator<< (std::ostream &stream, const time_range &t) {

stream << t.hour << ":" << t.minute;

return stream;

}

Однако, приведённый код не скомпилируется. Проблема в том, что поля hour и minute в классе time_range являются скрытыми (private), и у функции operator<< нет к ним доступа. Чтобы решить эту проблему, можно сказать, что эта функция является дружественной для класса time_range. Для этого нужно добавить прототип функции в объявление класса, поставив перед ним ключевое слово friend:

class time_range {

friend std::ostream& operator<< (std::ostream&,

const time_range&);

};

Аналогично дружественным функциям, можно создавать и дружественные классы. Если класс B является дружественным для класса A, то из методов класса B можно обращаться даже к скрытым и защищенным полям класса A. Рекомендуется не злоупотреблять данной возможностью, так как в хорошо спроектированной программе классы должны быть как можно более независимыми друг от друга: так их легче разрабатывать и отлаживать.

3.7 Статические элементы класса

Элементы класса могут объявляться со спецификатором static. Смысл использования этого спецификатора рассмотрим отдельно для полей и методов.

Статические поля. Такие поля существуют в одном экземпляре независимо от экземпляров класса. Память под такие поля выделяется в области глобальных и статических переменных до начала выполнения программы. Часто такие поля используются для хранения констант.

Например, предположим, что в некоторых методах класса complex_t требуется знать значение числа Пи. Тогда можно добавить в класс статическое константное поле, которое будет хранить это число. Вычислить число Пи можно, например, взяв арккосинус от минус единицы:

#include <cmath>

struct complex_t {

static const double PI;

};

const double complex_t::PI = acos(-1.0);

Внутри описания класса добавилось объявление статического поля PI. Инициализация этого поля производится в отдельной строке за пределами класса (если объявление класса обычно находится в файле с расширением .h, то инициализация − в файле с расширением .cpp). Для обращения к статическому полю пишется имя класса и операция ::, например:

cout << complex_t::PI;

Статические методы. Статический метод − это метод, который можно вызывать без создания экземпляра класса. Статические методы не имеют неявного параметра this и не могут обращаться к нестатическим элементам класса. В качестве примера добавим в класс time_range статический метод cur_time, возвращающий текущее время (для получения времени используются функции из заголовочного файла ctime):

#include <ctime>

class time_range {

...

static time_range cur_time() {

time_t t = time(0);

tm *ts = localtime(&t);

time_range res;

res.set(ts->tm_hour, ts->tm_min);

return res;

}

};

int main() {

time_range t = time_range::cur_time();

std::cout << t;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]