Дружественные типы данных
В некоторых случаях доступ через private – методы является слишком жёстким, ведь он требует дополнительных ресурсов – времени и памяти для организации вызова метода. Для смягчения ситуации С++ предлагает механизм дружественных (friend) типов данных, которыми могут быть: функции или операции, классы, функцииэлементов классов.
Если перечисленные типы данных объявлены как дружественные по отношению к некоторому классу, то они получают те же привилегии доступа, какими обладает метод того же класса. Например, если некий класс объявлен как дружественный к некоторому другому классу, то все его методы получают непосредственный доступ к переменным этого другого класса (естественно при надлежащей префиксации элементов).
Пример:
Пусть в ранее объявленном классе Time декларирован оператор *:
Time Time::operator* (double mult) const
{
Time result;
long totalminutes = hours*mult*60+minutes*mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
В этом случае выражение для ранее объявленых переменных A,B класса Time имеет смысл:
A=B*2.75;
Но оператор A = 2.75*B; является ошибкой. В языке имеется встроенная полиморфная операция *, но она не предусматривает преобразования типа второго аргумента из Time в double. Выходом является объявление дружественной операции. Внутри тела декларированного класса Time надо разместить:
friend Time operator*(double m, const Time&t);
Эта операция не является элементом класса Time. Аналогично объявляется функция – не операция. Объявление friend –класса или его отдельного метода делается подобным образом. Внутри декларации класса по отношению к которому необходимо объявить дружественные типы данных надо разместить:
friend class имя_класса;
Или
friend тип имя_класса::имя метода(список аргументов)[const];
В нашем конкретном случае определим реализацию дружественной операции так:
Time operator*(double m, const Time &t)
{return t*m;}
Мы учитываем, что для t имеется перегруженная операция *.
к реализации перегруженых операци и дружественных функций надо относиться очень внимательно, чтобы гарантировать то управление, которое не будет противоречить ожидаемому. |
Пример.
Имеется реализация следующей операции (декларация вне класса Time):
ostream& operator<<(ostream &os, const Time &t)
{
os<<t.hours<<” hours, “
<<t.minutes<<” minutes”;
return os;
}
?что даёт в реализации применение оператора return os;?
почему тип возвращаемого значения ostream&?
Вопросы для самоконтроля
· В чем отличие ссылочных переменных С++ от указателей?
· Для каких целей используется и какого типа указатель this?
· Как декларируются и инициализируются массивы объектов классов?
· Как выполняется перегрузка операций? – сколько аргументов необходимо указать в декларации перегружаемой операции?
· Для чего применяются дружественные типы данных? – может ли весь некоторый класс быть дружественным по отношению к другому классу?
Вопросы для самостоятельного изучения
· Выполните перегрузку для оператора «-» для представленного выше класса Time!
Лекция 21. С++: управление взаимными преобразованиями объектов и копирование объектов
Дата добавления: 2016-05-26; просмотров: 1645;