Цель работы: 1) изучить возможности программирования классов на языке С++; 2) получить основные навыки программирования. Теоретические сведения
Разрешить элементам другого класса полный доступ к элементам данного класса, объявленным как private или protected, можно включив в определение данного класса описание friend. Пример 1.
сlass myclass { friend class another_class; };
Разрешить обычной функции или функции-элементу другого класса полный доступ к элементам класса, объявленным private или protected, можно с помощью описания friend в определении данного класса. Пример 2.
сlass myclass { friend void another_class::member(int); friend void func_name(float); };
Для друзей существуют следующие правила: на описания friend не влияют спецификаторы public, protected или private; описания friend не взаимны: если А объявляет В другом, то это не означает, что А является другом для В; дружественность не наследуется: если А объявляет В другом, классы, производные от В, не будут автоматически получать доступ к элементам А; дружественность не является переходным свойством: если А объявляет В другом, классы, производные от А, не будут автоматически признавать дружественность В.
Функции-элементы класса могут быть перегружены. Две или несколько функций-элементов могут иметь одно и тоже имя, при условии, что списки их аргументов не совпадают. Пример 3.
class Time { char timestr[30]; public: Time(); // перегрузка конструкторов Time(char *str); };
Язык С++ позволяет определять и применять к классам обозначения операций. Эта особенность, называемая перегрузкой операций дает классам возможность вести себя подобно встроенному типу данных. Операции, допускающие перегрузку:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- ->* -> () []
Функции-операции и перегрузка операций подчиняются следующим правилам:
Пример 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 <cstdlib> #include <cstdio> #include "list.h" //конструктор инициализирует список из n элементов по принципу // "очередь" spisok::spisok (int n) { l = NULL; list *p,*pn; for (int i = 0; i<n; i++) { p = new list; p->inf = random(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) { printf ("%3d ",p->inf); p = p->next; } puts(""); } 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 <stdio.h> #include "list.h" int main (void) { spisok s1(10), // создание списка из 10 элементов s2(s1), // s2- копия списка s1 s3(15); // создание списка из 15 элементов s1.print(); // печать s1 s2.print(); // печать s2 s3.print(); // печать s3 printf("Значение третьего элемента в s1=%d \n",s1[3]); –s3; // сортировка s3 s3.print(); // и печать его return 0; }
В проект включены файлы: main.cpp и list.cpp. Результаты выполнения программы: -49 -50 -17 -47 -15 -29 3 -31 20 44 -49 -50 -17 -47 -15 -29 3 -31 20 44 -23 -6 -40 19 6 -46 -34 31 18 26 32 45 -29 -8 45 Значение третьего элемента в s1=-17 45 45 32 31 26 19 18 6 -6 -8 -23 -29 -34 -40 -46 Пример 5. Описать и определить класс файл и операции: = копирование файлов; -- определение самой короткой строки в файле. Файл описания класса file.h
class file { char *name; // имя файла FILE *f; // указатель на поток public: file (char *, char *); // конструктор file &operator = (file &); // операция копирования файлов friend char* operator --(file &); // операция поиска наименьшей строки ~file() { // деструктор fclose(f);delete name; }; };
Файл определения функций-элементов file.cpp
#include <stdio.h> #include <string.h> #include "file.h" file::file(char *n, char *attr) //конструктор - открывает файл { name = new char[strlen(n)+1]; strcpy (name, n); f=fopen (name, attr); } file& file::operator = (file &f1) //операция копирования файла { char stroka[120]; fseek (f1.f,0,0); while (fgets (stroka, 120, f1.f)) fputs (stroka, f); return *this; } char* operator -- (file &f1) //дружественная операция поиска // наименьшей строки в файле { fseek(f1.f, 0, 0); char *sent = new char[120]; int minlen = 120; char stroka[120]; while (fgets(stroka, 120, f1.f)) if (strlen(stroka) < minlen) { minlen = strlen(stroka); strcpy (sent, stroka); } return sent; }
Файл main_f.cpp с основной функцией.
#include <cstdio> #include "file.h" int main(void) { file f1("test1.txt", "rt"), // открытие файла для чтения f2("test2.txt", "wt"); // открытие файла для записи f2 = f1; //копирование файлов printf("Самая короткая строка = %s\n",f1--); return 0; }
Проект содержит файлы main_f.cpp и file.cpp.
Номер варианта | Задание |
---|---|
1 | Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Определить операции над строками: >> перевертывание строки (запись символов в обратном порядке); ++ нахождение наименьшего слова в строке. |
2 | Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Определить операции над строками: ++ преобразование символов строки в прописные (заглавные) символы; -- нахождение самого короткого слова в строке. |
3 | Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Определить операции над строками: + конкатенация двух строк; ++ преобразование символов строки в строчные (маленькие) символы. |
4 | Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Определить операции над строками: - удаление одной строки из другой (если одна строка является подстрокой другой); -- преобразование символов строки в строчные (маленькие) символы. |
5 | Определить класс список элементов. В определение класса включить два конструктора: для определения списка по его размеру и путем копирования другого списка. Определить операции над списком: | формирование нового списка из двух списков так, что каждый элемент информационного поля нового списка удовлетворяет условию: с=(а > b) ? a : b Определить функцию-элемент класса для вставки нового элемента в список на определенное место. |
6 | Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Определить операции над списком: & формирование нового списка из двух списков так, что каждый элемент информационного поля нового списка удовлетворяет условию: с=(а < b) ? a : b Определить функцию-элемент класса для удаления элемента с определенного места списка. |
7 | Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Определить операции над списком: ++ сортировка списка по возрастанию; -- расположение элементов списка в обратном порядке. |
8 | Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Определить операции над списком: [] получение значения информационного поля указанного элемента списка; – удаление из первого списка элементов второго, если второй список входит в первый. |
9 | Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Определить операции над списком: + конкатенация двух списков; & формирование нового списка из двух списка так, что каждый элемент информационного поля нового списка удовлетворяет условию: с=(а > b) ? a : b |
10 | Определить класс матрицу. В класс включить два конструктора для определения матрицы по количеству элементов и путем копирования другой матрицы. При задании матрицы предусмотреть ее заполнение случайными числами. Определить операции над матрицей: ++ нахождение наибольшего значения матрицы; + получение новой матрицы, каждый элемент которой равен сумме соответствующих элементов двух других матриц. |
11 | Определить класс матрицу. В класс включить два конструктора для определения матрицы по количеству элементов и путем копирования другой матрицы. При задании матрицы предусмотреть ее заполнение случайными числами. Определить операции над матрицей: -- нахождение наименьшего значения матрицы; - получение новой матрицы, каждый элемент которой равен разности элементов двух других матриц. |
12 | Определить класс стек. В класс включить два конструктора для определения стека по его размеру и путем копирования другого стека. Определить операции над стеком: + поместить элемент в стек; -- удалить элемент из стека. Определить две функции-элемента класса для выдачи на экран текущего элемента стека и содержимого стека. |
13 | Определить класс вектор. В класс включить два конструктора для определения вектора по его размеру и путем копирования другого вектора. При задании вектора по его размеру предусмотреть его заполнение случайными числами. Определить операции над векторами: & формирование нового вектора так, что каждый элемент нового вектора определяется следующим образом: c[i]=(a[i]>b[i])?a[i]:b[i]; ++ определить наибольший элемент вектора. |
14 | Определить класс вектор. В класс включить два конструктора для определения вектора по его размеру и путем копирования другого вектора. При задании вектора по его размеру предусмотреть его заполнение случайными числами. Определить операции над векторами: | формирование нового вектора так, что каждый элемент нового вектора определяется следующим образом: c[i]=(a[i]>b[i])?b[i]:a[i]; -- определить наименьший элемент вектора. |
15 | Определить класс вектор. В класс включить два конструктора для определения вектора по его размеру и путем копирования другого вектора. При задании вектора по его размеру предусмотреть его заполнение случайными числами. Определить операции над векторами: [] нахождение значения элемента вектора по заданному номеру; ++ сортировка элементов вектора по возрастанию. |