Witam,
mam za zadanie zrobić prosty kontener i obsłużyć wszystkie wyjątki typu wielkość tablicy równa 0, itd. Wszystko działa i to całkiem fajnie, ale pewnie w tym moim kodzie byłoby coś zwanego "zła praktyka", albo raczej "brak dobrej praktyki". Prosiłbym o "zrecenzowanie" moich prób, co należałoby poprawić / można by było zrobić lepiej.
Exceptions.hh
#include <iostream>
const std::size_t TAB_SIZE_MAX = 10000;
const std::size_t TAB_SIZE_MIN = 3;
class ZeroStackSizeException{};
class BaseArraySizeException
{
protected:
std::size_t size_;
public:
BaseArraySizeException(std::size_t size) : size_(size) {}
~BaseArraySizeException() {}
virtual void printError() const = 0;
};
class TooSmallArrayException : public BaseArraySizeException
{
public:
TooSmallArrayException(std::size_t size) : BaseArraySizeException(size) {}
void printError() const
{
std::cerr << "Rozmiar tablicy: " << size_ << " jest mniejszy niz "
<< TAB_SIZE_MIN << "!" << std::endl;
}
};
class ZeroArraySizeException : public TooSmallArrayException
{
public:
ZeroArraySizeException() : TooSmallArrayException(0) {}
void printError() const
{
std::cerr << "Rozmiar tablicy nie moze byc rowny 0!" << std::endl;
}
};
class TooBigArrayException : public BaseArraySizeException
{
public:
TooBigArrayException(std::size_t size) : BaseArraySizeException(size) {}
void printError() const
{
std::cerr << "Rozmiar tablicy: " << size_ << " jest wiekszy niz "
<< TAB_SIZE_MAX << "!" << std::endl;
}
};
Buffer.hh
#ifndef _BUFFER_H
#define _BUFFER_H
template <typename T>
class Buffer
{
protected:
T* arr_;
std::size_t capacity_;
std::size_t size_;
public:
Buffer(std::size_t);
Buffer(const Buffer &);
virtual ~Buffer();
Buffer<T>& operator = (const Buffer&);
};
#endif // _BUFFER_H
Buffer.cc
#include <iostream>
#include <new>
#include <stdexcept>
#include "Buffer.hh"
#include "Exceptions.hh"
template <typename T>
Buffer<T>::Buffer(std::size_t capacity) : capacity_(capacity), size_(0)
{
if(capacity_ == 0)
throw ZeroArraySizeException();
if(capacity_ < TAB_SIZE_MIN)
throw TooSmallArrayException(capacity_);
if(capacity_ > TAB_SIZE_MAX)
throw TooBigArrayException(capacity_);
try
{
arr_ = new T[capacity_];
}
catch(const std::bad_alloc &e)
{
std::cerr << "Nie udalo sie zaalokowac pamieci: " << e.what() << std::endl;
}
}
template <typename T>
Buffer<T>::Buffer(const Buffer &buffer) : capacity_(buffer.capacity_),
size_(buffer.size_)
{
try
{
arr_ = new T[capacity_];
}
catch(const std::bad_alloc &e)
{
std::cerr << "Nie udalo sie zaalokowac pamieci: " << e.what() << std::endl;
}
for(std::size_t i = 0; i < size_; ++i)
arr_[i] = buffer.arr_[i];
}
template <typename T>
Buffer<T>::~Buffer()
{
delete [] arr_;
}
template <typename T>
Buffer<T> & Buffer<T>::operator = (const Buffer &buffer)
{
if(this != &buffer)
{
delete [] arr_;
capacity_ = buffer.capacity_;
size_ = buffer.size_;
try
{
arr_ = new T[capacity_];
}
catch(const std::bad_alloc &e)
{
std::cerr << "Nie udalo sie zaalokowac pamieci: " << e.what() << std::endl;
}
for(std::size_t i = 0; i < size_; ++i)
arr_[i] = buffer.arr_[i];
}
return *this;
}
Stack.hh
#ifndef _STACK_HH
#define _STACK_HH
#include <iostream>
#include "Buffer.hh"
template <typename T>
class Stack : public Buffer<T>
{
public:
Stack(const std::size_t capacity) : Buffer<T>(capacity) {}
Stack(const Stack &buffer) : Buffer<T>(buffer) {};
Stack<T>& operator = (const Stack&) = default; // to implementuje kompilator
~Stack() = default; // i to tez (tak dziala slowo default)
void push(const T&);
void pop();
T& top();
};
#endif // _STACK_HH
Stack.cc
#include "Stack.hh"
#include "Exceptions.hh"
template <typename T>
void Stack<T>::push(const T& el)
{
if(this->size_ + 1 > this->capacity_)
throw std::out_of_range("Przepelnienie zakresu stosu!");
this->arr_[this->size_++] = el;
}
template <typename T>
void Stack<T>::pop()
{
if(this->size_ == 0)
throw ZeroStackSizeException();
--(this->size_);
}
template <typename T>
T& Stack<T>::top()
{
if(this->size_ == 0)
throw ZeroStackSizeException();
return this->arr_[this->size_ - 1];
}
Main.cc
#include <iostream>
#include <new>
#include <stdexcept>
#include "Exceptions.hh"
#include "Buffer.cc"
#include "Stack.cc"
void f1();
void f2();
void f1()
{
//Stack<int> abcd(0);
//Stack<int> abc(2);
//Stack<int> ab(1e10);
Stack<int> a(4);
//a.top();
//a.pop();
a.push(1);
a.push(2);
a.push(3);
a.push(4);
std::cout << "Ostatni element: " << a.top() << std::endl;
//a.push(5);
a.pop();
std::cout << "Ostatni element: " << a.top() << std::endl;
}
void f2()
{
try
{
f1();
}
catch(BaseArraySizeException &e)
{
e.printError(); // wykorzystanie polimorfizmu
}
catch(const std::out_of_range &e)
{
std::cerr << e.what() << std::endl;
}
catch(ZeroStackSizeException)
{
std::cerr << "Jesli chcesz usunac lub zwrocic ostatni element, " <<
"to stos nie moze byc pusty!" << std::endl;
}
catch(const std::exception &e)
{
std::cerr << "Wystapil nieznany blad z biblioteki standardowej: " << e.what() << std::endl;
}
catch(...)
{
std::cerr << "Wystapil nieznany blad!" << std::endl;
}
}
int main(void)
{
f2();
return 0;
}
jeśli ktoś chciałby sobie skompilować kod, to w załączniku jest kod + makefile