Добавил:
CanyonE
СПбГУТ * ИКСС * Программная инженерия
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Решения лабораторных работ (местами есть ошибки) / Lab5_2_DynArray
.cpp#include <iostream>
#include <stdexcept>
using std::cin;
using std::cout;
using std::endl;
// Динамический одномерный вектор-массив
template <class T>
class DynArray {
private:
// Текущий размер массива
size_t n_;
// Резервируемый размер массива (m_ >= n_)
size_t m_ = 10;
// Указатель на массив из m_ элементов
T *values_ = nullptr;
protected:
// Стандартное количество резервируемых элементов в массиве
size_t standart = 10;
public:
// Конструктор
explicit DynArray(size_t n = 0) : n_(n) {
if (n >= m_) {
m_ = n * 2;
}
values_ = new T[m_] {0};
}
// Конструктор копирования
DynArray(const DynArray &da) : DynArray(da.n_) {
n_ = da.n_;
std::copy(da.values_, da.values_ + n_, values_);
}
// Оператор копирования
DynArray &operator=(const DynArray &da) {
DynArray temp(da);
swap(*this, temp);
return *this;
}
// Конструктор перемещения
DynArray(DynArray &&da) noexcept {
n_ = da.n_, m_ = da.m_, values_ = da.values_, standart = da.standart;
da.n_ = 0, da.m_ = 0, da.values_ = nullptr;
}
// Оператор перемещения
DynArray &operator=(DynArray &&da) noexcept {
if (this != &da) {
swap(*this, da);
delete[] da.values_, da.values_ = nullptr;
da.n_ = 0, da.m_ = 0;
}
return *this;
}
// Деструктор
virtual ~DynArray() {
delete[] values_;
}
// Оператор получения элемента по индексу I
T &operator[](size_t i) {
return values_[i];
}
// [static] Получение размера массива
static size_t size(const DynArray &da) {
return da.n_;
}
// Добавление K элементов из массива DA в конец
void add(const DynArray &da, const size_t &k) {
size_t mn = std::min(DynArray::size(da), k);
for (size_t i = 0; i < k; ++i) {
push_back(da.values_[i]);
}
}
// Вставка элемента D в позицию K
void insert(const T &d, const size_t &k) noexcept(false) {
if (k == 0) {
push_front(d);
return;
} else if (k == n_) {
push_back(d);
return;
} else if (k > 0 && k < n_) {
push_back(d);
T t = values_[k], p;
for (size_t i = k; i < n_; ++i) {
p = values_[i], values_[i] = t, t = p;
}
values_[k] = d;
return;
}
throw std::out_of_range("DynArray. Method insert. Out of range");
}
// Добавление элемента D в конец
void push_back(const T &d) {
if (n_ < m_) {
values_[n_] = d, ++n_;
return;
}
T *b = values_;
values_ = new T[m_ * 2] {0};
std::copy(b, b + n_, values_);
delete[] b;
m_ *= 2;
}
// Добавление элемента D в начало
void push_front(const T &d) {
push_back(d);
T t = values_[0], p;
for (size_t i = 1; i < n_; ++i) {
p = values_[i], values_[i] = t, t = p;
}
values_[0] = d;
}
// Очистка массива
void clear() {
delete[] values_;
values_ = new T[standart] {0};
n_ = 0, m_ = standart;
}
// Получение размера массива
size_t size() const noexcept { return n_; }
// Пустой ли массив
bool empty() const noexcept { return n_ == 0; }
// Удаление элемента с индексом I
T erase(size_t i) noexcept(false) {
if (n_ > 0 && i < n_) {
T d = 0;
d = values_[i];
std::copy(values_ + i + 1, values_ + n_, values_ + i);
--n_;
return d;
}
throw std::out_of_range("DynArray. Method erase. Out of range");
}
// Удаление первого (нулевого) элемента
T pop_front() {
return erase(0);
}
// Удаление последнего элемента
T pop_back() {
T d = 0;
if (n_ > 0) {
d = values_[n_ - 1], --n_;
}
return d;
}
// Оператор приведения к типу bool
explicit operator bool () {
return n_ != 0;
}
// Дружественный оператор для вывода массива в ostream (cout, ...)
friend std::ostream &operator<<(std::ostream &os, const DynArray &da) {
if (da.n_ > 0) {
os << da.values_[0];
for (size_t i = 1; i < da.n_; ++i) {
os << ' ' << da.values_[i];
}
}
return os;
}
friend void swap(DynArray &first, DynArray &second) noexcept {
std::swap(first.standart, second.standart);
std::swap(first.values_, second.values_);
std::swap(first.m_, second.m_);
std::swap(first.n_, second.n_);
}
};
int main() {
DynArray<double> da, db(5);
da.push_back(1);
da.push_back(2);
da.push_back(3);
da.push_back(4);
da.push_front(1);
da.push_front(2);
da.push_front(3);
da.push_front(4);
cout << "First array (after push_back and push_front): " << da << endl;
db.add(da, da.size());
cout << "Second array (5 empty + method add from first array): " << db << endl;
for (size_t i = 0; i < da.size(); ++i) {
da[i] = i + 1;
}
cout << "First array (after reinitialize): " << da << endl;
cout << "First array size: " << da.size() << " (isEmpty ? " << ( da.empty() ? "TRUE" : "FALSE" ) << ")\n";
da.clear();
cout << "First array cleared: " << da << endl;
cout << "First array size: " << da.size() << " (isEmpty ? " << ( da.empty() ? "TRUE" : "FALSE" ) << ")\n";
db.insert(-6, 2);
db.insert(-7, 2);
db.insert(-8, 2);
db.insert(-9, 2);
cout << "Second array (insert -6, -7, -8, -9): " << db << endl;
cout << "Second array (erased " << db.erase(2) << ")\n";
cout << "Second array (erased " << db.erase(2) << ")\n";
cout << "Second array (erased " << db.erase(2) << ")\n";
cout << "Second array (erased " << db.erase(2) << ")\n";
cout << "Second array: " << db << endl;
cout << "Second array (pop_front " << db.pop_front() << ")\n";
cout << "Second array (pop_front " << db.pop_front() << ")\n";
cout << "Second array: " << db << endl;
cout << "Second array (pop_back " << db.pop_back() << ")\n";
cout << "Second array (pop_back " << db.pop_back() << ")\n";
cout << "[Input] Old array: " << db << endl;
DynArray<double> dc(db); // Конструктор копирования
cout << "[Output] Old array (after copy): " << db << endl;
cout << "[Output] New array (after copy construct): " << dc << endl;
cout << "[Input] Old array: " << dc << endl;
db = dc; // Оператор копирования
cout << "[Output] Old array (after copy): " << dc << endl;
cout << "[Output] New array (after copy assignment): " << db << endl;
cout << "[Input] Old array: " << db << endl;
DynArray<double> df(std::move(db)); // Конструктор перемещения
cout << "[Output] Old array (after move): " << db << endl;
cout << "[Output] New array (after move construct): " << df << endl;
cout << "[Input] Old array: " << df << endl;
db = std::move(df); // Оператор перемещения
cout << "[Output] Old array (after move): " << df << endl;
cout << "[Output] New array (after move assignment): " << db << endl;
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)