Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
14_перегрузка_14.doc
Скачиваний:
13
Добавлен:
10.04.2019
Размер:
113.66 Кб
Скачать

Лабораторная работа №14 Перегрузка операторов Дружественные классы

Разрешить элементам другого класса полный доступ к элементам данного класса, объявленным как private или protected, можно включив в определение данного класса описание friend.

Пример 14.1.

сlass myclass

{ friend class another_class; };

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

Разрешить обычной функции или функции-элементу другого класса полный доступ к элементам класса, объявленным private или protected, можно с помощью описания friend в определении данного класса.

Пример 14.2.

сlass myclass

{ friend void another_class::member(int);

friend void func_name(float);

};

Для друзей существуют следующие правила:

  • на описания friend не влияют спецификаторы public, protected или private;

  • описания friend не взаимны: если А объявляет В другом, то это не означает, что А является другом для В;

  • дружественность не наследуется: если А объявляет В другом, классы, производные от В, не будут автоматически получать доступ к элементам А;

  • дружественность не является переходным свойством: если А объявляет В другом, классы, производные от А, не будут автоматически признавать дружественность В.

Перегрузка операций

Язык С++ позволяет определять и применять к классам обозначения операций. Эта особенность, называемая перегрузкой операций дает классам возможность вести себя подобно встроенному типу данных.

Операции, допускающие перегрузку:

+  * / % ^ & | ~ ! = < > += = *= /= %= ^= &=

|= << >> <<= >>= == != <= >= && || ++  >* > () [ ]

Функции-операции и перегрузка операций подчиняются следующим правилам:

  • приоритеты операций и правила ассоциации, принятые для встроенных типов данных, остаются неизменными при оценке выражений с перегруженными функциями-операциями;

  • функция-операция не может изменить поведение операции по отношению к встроенным типам данных;

  • функция-операция должна быть либо элементом класса, либо воспринимать один или несколько аргументов, имеющих тип класса;

  • функция-операция не может иметь аргументов по умолчанию;

за исключением operator=() функции-операции наследуются.

Примеры программирования

Пример 14.4.

Описать и определить класс-список, операцию –, как сортировка списка по убыванию и операцию [ ] получения значения по заданному номеру.

Файл list.h содержит описание класса.

struct list

{ int inf; // информационное поле

list *next; // указатель на следующий элемент списка

};

class spisok

{ list* l; // указатель на начало списка

public:

spisok (int);

spisok (spisok&);

void print ();

int operator [ ](int);

friend void operator - (spisok&);

~spisok();

};

Файл list.cpp содержит определение функций-элементов.

#include "stdafx.h"

#include <stdlib.h>

#include "list.h"

#include <iostream>

#include <iomanip>

using namespace std;

spisok::spisok (int n)

//конструктор инициализирует список из n элементов по принципу

// "очередь"

{ l = NULL;

list *p,*pn;

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

{ p = new list;

p->inf = rand()%100-50;

p->next = NULL;

if (l == NULL) l = p;

else pn->next = p;

pn = p;

}

}

spisok::spisok (spisok& s)

//конструктор копии класса spisok

{ l = NULL;

list *sp = s.l, *p, *pn;

while (sp)

{ p = new list;

p->inf = sp->inf;

p->next = NULL;

if (l == NULL) l = p;

else pn->next = p;

pn = p;

sp = sp->next;

}

}

spisok::~spisok()

//деструктор - уничтожает объект класса список из памяти

{ list *p;

while ( l )

{ p = l;

l = l->next;

delete p;

}

}

void spisok::print()

//функция-элемент печати содержимого списка

{ list *p = l;

while (p)

{

cout<<setw(4)<<p->inf;

p = p->next;

}

cout<<endl;

}

int spisok::operator [ ] (int n)

//перегруженная операция получения значения по заданному номеру n

{ list *p = l;

for (int i = 1; (i<n )&& (p!=NULL); i++, p = p->next);

if (p) return p->inf;

return -1000;

}

void operator - (spisok& s)

//дружественный перегруженный оператор сортировки элементов

// списка по убыванию

{ list *p = s.l;

while (p)

{ list *max = p, *pn = p->next;

while (pn)

{ if (pn->inf > max->inf) max = pn;

pn = pn->next;

}

int i = max->inf;

max->inf = p->inf;

p->inf = i;

p = p->next;

}

}

Файл main.cpp содержит основную функцию.

#include "stdafx.h"

#include "list.h"

#include <conio.h>

#include <stdlib.h>

#include <time.h>

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

srand((unsigned)time(NULL));

setlocale(LC_ALL, "Russian");

spisok s1(10), // создание списка из 10 элементов

s2(s1), // s2- копия списка s1

s3(15); // создание списка из 15 элементов

s1.print(); // печать s1

s2.print(); // печать s2

s3.print(); // печать s3

cout<<"Значение третьего элемента в s1="<<s1[3]<<endl;

-s3; // сортировка s3

s3.print(); // и печать его

_getch();

return 0;

}

В проект включены файлы: main.cpp и list.cpp, list.h.