Для студентов МГТУ им. Н.Э.Баумана по предмету Информатика(C++) «Классы. Шаблоны классов. Переопределение операторов. Инкапсуляция.» (C++) «Классы. Шаблоны классов. Переопределение операторов. Инкапсуляция.»
5,0051
2023-09-262023-09-26СтудИзба
Лабораторная работа: (C++) «Классы. Шаблоны классов. Переопределение операторов. Инкапсуляция.» вариант 2
Описание
Задание:
Инкапсуляция. 1. Инкапсуляция. Массив переменной длины. Переопределение операторов. Необходимо описать пользовательский тип данных MyIntVector (будем для краткости называть его в рамках этого задания вектор). Требуется, чтобы с переменными этого типа можно было обращаться как с обычными массивами типа int. Т.е. чтобы в программе с определенной переменной vec типа MyIntVector можно было выполнять операции обращения к элементам по индексу. MyIntVector vec; … vec[0] = 10; int q = vec[2]; Пусть в основе нашего вектора лежит динамический массив целых чисел. Память под этот массив должна выделяться и перевыделяться по мере необходимости автоматически. Пусть считается, что только что созданный вектор по умолчанию имеет 0 элементов и потенциально может хранить 1 (под динамический массив выделена память размером в 1 элемент). Ниже приведен пример объявления такого вектора. class MyIntVector { //открытые методы класса (открытые функции-члены, интерфейс) public: //Конструктор инициализирует поля объекта MyIntVector () : length(0), capacity(1), dataPointer(new int[1]) { } //Такой синтаксис конструктора выбран в иллюстративных целях ~MyIntVector (); //Пользовательсий деструктор void PushBack (int newElement); //Метод добавляет новый элемент в конец вектора и увеличивает логическую длину на 1 int &operator[] (int index); //Оператор получения ссылки на элемент вектора bool IsEmpty () const; //Метод возвращает true, если логический размер равен 0 int Length () const; //Метод возвращает логическую длину int Capacity () const; //Метод возвращает физическую длину private: //реализация //закрытые методы класса (закрытые функции-члены) void UpCapacity (int newCapacity); //Метод увеличения размера блока памяти //поля класса (данные-члены) int length; //текущее логическое количество элементов вектора (логическая длина) int capacity; //количество элементов динамического блока памяти (физическая длина) int *dataPointer; //указатель на динамический блок памяти }; Пусть для начала увеличение логической и физической длины вектора происходит только за счет добавления новых элементов в его конец. Эту функцию реализует метод PushBack. Ниже приведен пример использования такой функции. MyIntVector vec; for (int i = 0; i < 7; ++i) { vec.PushBack(i); } 2 По результатам выполнения этого кода логический размер вектора должен стать равным 7. Он будет состоять из 7 элементов типа int (0,1,2,3,4,5,6), и их можно будет вывести на экран следующим образом: for (int i = 0; i < vec.Length(); ++i) { printf("%i ", vec[i]); } Обратите особое внимание на то, что наш вектор в отличие от обычного массива хранит количество своих элементов. Очевидно, что при последовательном применении метода PushBack придется увеличивать не только логическую длину вектора, но и сам физический размер блока памяти, на который указывает dataPointer. Пусть за это отвечает закрытый метод UpCapacity. Он принимает на вход целое число – новый физический размер. Если этот размер больше текущего, то выделяется новый участок в динамической памяти, затем в него копируется текущее содержимое вектора. После чего старая память освобождается, а указателю dataPointer присваивается новое значение. Реализуйте объявленные функции и проверьте возможность заполнения вектора новыми элементами. Напишите отдельные функции для ввода вектора с клавиатуры и вывода его на экран. void InputMyIntVector (MyIntVector &inVector, int N); void OutputMyIntVector (const MyIntVector &outVector); Пусть функция ввода вектора ожидает ввода N целых чисел с клавиатуры. 2. Шаблоны функций. Шаблоны классов. Напишите шаблон функции обмена элементов одинакового типа: template void MySwap (MyType &element1, MyType & element2) { MyType element3 = element1; element1 = element2; element2 = element3; } Убедитесь, что она работает для элементов типа char. (MySwap) Попробуйте применить ее к элементам типа MyIntVector. Почему функция не работает? Переопределите конструктор копирования по умолчанию и оператор присваивания так чтобы корректно копировались данные динамической памяти. MyIntVector (const MyIntVector &rhs); //Пользовательсий конструктор копирования MyIntVector &operator= (const MyIntVector &rhs); //Пользовательсий оператор присваивания Возможно, для реализации безопасного обращения к элементам массива rhs понадобится определить еще один метод At. const int &At (int index) const { return dataPointer [index]; } Добейтесь корректной работы внешней функции обмена. (MySwap) Напишите шаблонную версию вектора для хранения элементов произвольного типа TypeOfElement. template class MyVector { … }; Убедитесь, что для шаблонной версии работает внешняя функция обмена (MySwap<MyVector>). 3 Следующее задание требуется выполнить в соответствии со своим вариантом. Однако для достижения самого лучшего понимания рекомендуется выполнить все варианты. Далее необходимо улучшить реализацию шаблонного класса MyVectorЭффективно ли использование внешней функции обмена для векторов? Добавить метод swap для эффективного обмена полей двух векторов. void Swap(MyIntVector &); //Метод обмена двух векторов Правильно ли у Вас реализован оператор присваивания? Не происходит ли утечек памяти? Что случиться, если произойдет присваивание объекта самому себе? (MyVector a; a=a;). Попробуйте осуществить присваивание через последовательное копирование (конструктором копирования) и обмен (внутренней функцией обмена).
Файлы условия, демо
Характеристики лабораторной работы
Предмет
Учебное заведение
Семестр
Вариант
Теги
Просмотров
48
Размер
553,69 Kb
Список файлов
ЛР-17.pdf