Добавил:
CanyonE
СПбГУТ * ИКСС * Программная инженерия
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Решения лабораторных работ (местами есть ошибки) / Lab5_2_Stack (array)
.cpp#include <iostream>
#include <stdexcept>
using std::cin;
using std::cout;
using std::endl;
// Стек на основе динамического одномерного массива
// Принцип:
// push -> добавляет элемент в начало (на самом деле в конец массива values_)
// pop -> удаляет элемент из начала (на самом деле из конца массива values_)
template <class T>
class StackArray {
private:
// Текущий размер стека
size_t n_;
// Резервируемый размер стека (m_ >= n_)
size_t m_ = 10;
// Указатель на массив из m_ элементов
T *values_ = nullptr;
protected:
// Стандартное количество резервируемых элементов
size_t standart = 10;
public:
// Конструктор
explicit StackArray() {
n_ = 0;
values_ = new T[m_] {0};
}
// Конструктор копирования
StackArray(const StackArray &arg) {
n_ = arg.n_, m_ = arg.m_;
values_ = new T[m_] {0};
std::copy(arg.values_, arg.values_ + n_, values_);
}
// Оператор копирования
StackArray &operator=(const StackArray &arg) {
StackArray temp(arg);
swap(*this, temp);
return *this;
}
// Конструктор перемещения
StackArray(StackArray &&arg) noexcept {
n_ = arg.n_, m_ = arg.m_, values_ = arg.values_, standart = arg.standart;
arg.n_ = 0, arg.m_ = 0, arg.values_ = nullptr, arg.standart = 10;
}
// Оператор перемещения
StackArray &operator=(StackArray &&arg) noexcept {
if (this != &arg) {
swap(*this, arg);
delete[] arg.values_, arg.values_ = nullptr;
arg.n_ = 0;
}
return *this;
}
// Деструктор
virtual ~StackArray() {
delete[] values_;
}
// Получение размера стека
size_t size() const { return n_; }
// Вставка элемента "на верх" (на самом деле в конец)
StackArray &push(const T &d) {
if (n_ < m_) {
values_[n_] = d, ++n_;
return *this;
}
T *b = values_;
values_ = new T[m_ * 2] {0};
memcpy(values_, b, sizeof(T) * n_);
delete[] b;
m_ *= 2;
return *this;
}
// Получение доступа к верхнему элементу
T &top() const noexcept(false) {
if (values_) {
return values_[n_ - 1];
} else { throw std::out_of_range("StackArray. Method top. Out of range"); }
}
// Очистка стека
void clear() {
delete[] values_;
values_ = new T[standart] {0};
n_ = 0, m_ = standart;
}
// Пустой ли стек
bool empty() const noexcept { return n_ == 0; }
// Удаление и возвращение копии элемента из верха (на самом деле последнего)
T pop() {
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 StackArray &arg) {
if (arg.n_ > 0) {
os << arg.n_ << " : [" << arg.values_[arg.n_ - 1] << "]";
}
for (size_t i = 2; i <= arg.n_; ++i) {
os << ", " << ( arg.n_ - i + 1 ) << " : [" << arg.values_[arg.n_ - i] << ']';
}
return os;
}
friend void swap(StackArray &first, StackArray &second) noexcept {
std::swap(first.n_, second.n_);
std::swap(first.m_, second.m_);
std::swap(first.values_, second.values_);
std::swap(first.standart, second.standart);
}
};
int main() {
StackArray<double> stackA, stackB;
// Добавление элементов на верх
stackA.push(111).push(222).push(333).push(444);
stackB.push(444).push(555).push(666);
// Отображение содержимого стеков
cout << "Stack A: " << stackA << endl;
cout << "Stack B: " << stackB << endl;
// Доступ к вершине стека и удаление верхнего элемента
cout << "Stack A [top(), pop()]: " << stackA.top() << endl;
stackA.pop();
cout << "Stack B [top(), pop()]: " << stackB.top() << endl;
stackB.pop();
// Конструктор копирования
StackArray<double> stackC(stackA);
cout << "Stack (after copy): " << stackA << " (top: " << stackA.top() << ")\n";
cout << "Copy ^ (constructor): " << stackC << " (top: " << stackC.top() << ")\n";
// Оператор копирования
stackC = stackB;
cout << "Stack (after copy): " << stackB << " (top: " << stackB.top() << ")\n";
cout << "Copy ^ (assignment): " << stackC << " (top: " << stackC.top() << ")\n";
// Конструктор перемещения
StackArray<double> stackD(std::move(stackA));
cout << "Stack (after move): " << stackA << endl;
cout << "Move ^ (constructor): " << stackD << " (top: " << stackD.top() << ")\n";
// Оператор перемещения
stackC = std::move(stackB);
cout << "Stack (after move): " << stackB << endl;
cout << "Move ^ (assignment): " << stackC << " (top: " << stackC.top() << ")\n";
// Размер стека
cout << "Stack D (size): " << stackD.size() << " (isEmpty ? " << ( stackD.empty() ? "TRUE" : "FALSE" ) << ")\n";
cout << "Stack C (size): " << stackC.size() << " (isEmpty ? " << ( stackC.empty() ? "TRUE" : "FALSE" ) << ")\n";
stackD.pop(), stackD.pop(), stackD.pop();
stackC.clear();
cout << "Stack D (size after pop): " << stackD.size() << " (isEmpty ? " << ( stackD.empty() ? "TRUE" : "FALSE" )
<< ")\n";
cout << "Stack C (size after pop): " << stackC.size() << " (isEmpty ? " << ( stackC.empty() ? "TRUE" : "FALSE" )
<< ")\n";
// Работа деструктора...
stackD.push(111).push(222).push(333).push(444);
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)