Скачиваний:
1
Добавлен:
15.08.2023
Размер:
25.28 Кб
Скачать

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ "САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА"

Факультет инфокоммуникационных сетей и систем

Кафедра сетей связи и передачи данных

ЛАБОРАТОРНАЯ РАБОТА №5

«ШАБЛОНЫ КЛАССОВ»

по дисциплине «Объектно-ориентированное программирование»

Выполнил:

студент 2-го курса

дневного отделения

группы ИКПИ-92

Козлов Никита

Санкт-Петербург

2020

Постановка задачи

В настоящей лабораторной работе необходимо решить две задачи, связанные с организацией шаблонов классов. Первая из задач состоит в преобразовании в шаблон класс того числового класса, который был разработан студентом в первой лабораторной работе по ООП. Вторая задача состоит в разработке шаблона контейнера. При решении второй задачи следует предусмотреть обработку исключительных ситуаций.

Вариант второй задачи

Задача № 3.

Разработать шаблон класса для стека, построенного на основе массива с фиксированными размерами.

Файл vector.h

#ifndef VECTOR_H

#define VECTOR_H

#include <iostream>

#include <assert.h>

template <typename T>

class Vector

{

private:

size_t length = 0; // length of array

T* buffer = NULL; // array eq to null pointer

public:

Vector(); // Default constructor

Vector(const Vector& r); // Copy constuctor

Vector(int _length); // Constructor with given length

~Vector() { delete[] buffer; buffer = NULL; }; // Destructor

void print(); // Print each element of Vector array

size_t len(void) { return length; } // Returns legth of Vector array

template<typename U> friend U dot_product(const Vector<U>& v1, const Vector<U>& v2);

Vector operator = (const Vector& source);

Vector operator + (const Vector& other);

T& operator [] (const size_t index);

template<typename U> friend Vector<U> operator-(const Vector<U>& v1, const Vector<U>& v2);

};

#pragma region Vector objects

template <class T> Vector<T>::Vector()

{

Vector(20);

}

template <typename T> Vector<T>::Vector(int _length) :length(_length)

{

try

{

#pragma region exceptions

if (_length <= 0)

throw exception("Vector size cannot be equal to or less than zero");

#pragma endregion

buffer = new T[length];

for (size_t i = 0; i < length; i++)

buffer[i] = 0;

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

template <class T> Vector<T>::Vector(const Vector& arg) :length(arg.length)

{

buffer = new T[this->length];

for (size_t i = 0; i < arg.length; i++)

buffer[i] = arg.buffer[i];

}

template<class T> void Vector<T>::print()

{

cout << "{ ";

for (size_t i = 0; i < this->length; i++)

cout << "'" << buffer[i] << "' ";

cout << "}\n";

}

template<typename U> U dot_product(const Vector<U>& v1, const Vector<U>& v2)

{

try

{

U res = 0;

assert(v1.length == v2.length && throw exception("The arrays lengths must be equal"));

for (size_t i = 0; i < v1.length; ++i)

res += v1.buffer[i] * v2.buffer[i];

return res;

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

#pragma endregion

// Operators

#pragma region Vector operators

template<typename T>

Vector<T> Vector<T>::operator=(const Vector& source)

{

length = source.length;

buffer = new T[length];

for (size_t i = 0; i < length; i++)

buffer[i] = source.buffer[i];

return *this;

}

template <typename T>

Vector<T> Vector<T>::operator+(const Vector& arg)

{

try

{

#pragma region exceptions

if (length != arg.length)

{

throw exception("Vectors doesn't match by size");

}

#pragma endregion

Vector<T>temp(length);

for (size_t i = 0; i < length; i++)

temp.buffer[i] = buffer[i] + arg.buffer[i];

return temp;

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

exit(1);

}

}

template<typename T>

T& Vector<T>::operator[](const size_t index)

{

try

{

assert(index >= 0 && index < length && throw exception("Invalid array index"));

return buffer[index];

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

template<typename U>

Vector<U> operator-(const Vector<U>& v1, const Vector<U>& v2)

{

assert(v1.length == v2.length && "The array lengths must be equal");

Vector<U> temp(v1.length);

for (size_t i = 0; i < v1.length; i++)

temp.buffer[i] = v1.buffer[i] - v2.buffer[i];

return temp;

}

#pragma endregion

#endif // !VECTOR_H

Файл stack_t.h

#ifndef STACK_T_H

#define STACK_T_H

#include <iostream>

#define definit 0

using namespace std;

/// <summary>

/// Simple stack structure, based on limited array;

/// </summary>

template<typename T>

class stack_t

{

private:

// Buffer length

uint_fast32_t length;

T* buffer = NULL;

// Stack end pointer

uint_fast16_t end;

// Stack start pointer

uint_fast16_t start;

void indexide();

void reindexide();

public:

/// <summary>

/// Default stack_t constructor

/// </summary>

stack_t() { stack_t(5); };

/// <summary>

/// Stack_t constructor with given array size

/// </summary>

/// <param name="_length">Array length</param>

stack_t(uint_fast32_t _length);

// Stack_t destructor

~stack_t() { delete[]buffer; buffer = NULL;};

/// <summary>

/// Push argument on the top of the stack

/// </summary>

/// <param name="arg">- argument to push</param>

void push(T arg);

/// <summary>

/// Delte argument from the top of the stack

/// </summary>

void pop();

/// <summary>

/// Print all stack with formating

/// </summary>

void print();

/// <summary>

/// </summary>

/// <returns>true if stack empty</returns>

bool isEmpty();

/// <summary>

/// </summary>

/// <returns>true if stack full</returns>

bool isFull();

/// <summary>

///

/// </summary>

/// <returns>stack size</returns>

uint_fast32_t size();

};

#pragma region public

template<typename T>

inline stack_t<T>::stack_t(uint_fast32_t _length) :length(_length)

{

try

{

#pragma region exceptions

if (_length <= 0)

throw exception("stack size cannot be equal to zero");

#pragma endregion

buffer = new T[this->length];

for (uint_fast32_t i(0); i < this->length; i++)

this->buffer[i] = 0;

indexide();

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

template<typename T>

inline bool stack_t<T>::isEmpty()

{

if (this->buffer[end] == definit)

return true;

else

return false;

}

template<typename T>

inline bool stack_t<T>::isFull()

{

if (buffer[0] == definit)

return false;

else

return true;

}

template<typename T>

inline uint_fast32_t stack_t<T>::size()

{

return this->length;

};

template<typename T>

inline void stack_t<T>::push(T arg)

{

try

{

#pragma region exceptions

if (this->buffer == nullptr)

throw exception("buffer null pointer error");

if (this->buffer[0] != definit)

throw exception("Unable to place argument in stack because of overflow");

if (arg == 0)

throw exception("0 can't be a part of the stack");

#pragma endregion

if (isEmpty())

{

this->buffer[end] = arg;

reindexide();

}

else

{

for (size_t i(this->length); i != -1; --i)

{

if (this->buffer[i] == definit & this->buffer[i + 1] != definit)

{

this->buffer[i] = arg;

reindexide();

break;

}

}

}

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

template<typename T>

inline void stack_t<T>::pop()

{

this->buffer[start] = definit;

reindexide();

}

#pragma endregion

#pragma region private

template<typename T>

inline void stack_t<T>::indexide()

{

this->end = this->length - 1;

this->start = this->length - 1;

}

template<typename T>

inline void stack_t<T>::reindexide()

{

this->end = this->length - 1;

for (size_t i(0); i < length; i++)

{

if (buffer[i] != definit)

{

this->start = i;

break;

}

}

}

#pragma endregion

template<typename T>

inline void stack_t<T>::print()

{

try

{

#pragma region exceptions

if (this->buffer == nullptr)

throw exception("this->buffer was 0x1110112");

#pragma endregion

cout << "[";

for (size_t i(start); i < length; i++)

cout << " '" << this->buffer[i] << "' ";

cout << "]" << endl;

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

};

#endif // !STACK_T_H

Файл main.cpp

#include <iostream>

#include "Stack_t.h"

#include "vector.h"

using namespace std;

void main()

{

stack_t<int> a(3);

a.push(4);

a.print();

a.push(9);

a.print();

a.push(2);

a.print();

a.pop();

a.print();

Vector<int> b(5);

for (int i = 0; i < b.len(); i++)

b[i] = i + 2;

b.print();

}