Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный платный хостинг на базе Windows 2008

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

_Ayl_
Статус: 8-й класс
Рейтинг: 592
∙ повысить рейтинг >>
Micren
Статус: Практикант
Рейтинг: 360
∙ повысить рейтинг >>
AMV007
Статус: 3-й класс
Рейтинг: 139
∙ повысить рейтинг >>

∙ / КОМПЬЮТЕРЫ И ПО / Языки программирования / C/C++

Выпуск № 1347 от 01.07.2009, 17:05
Администратор рассылки: Dr_Andrew, Модератор
В рассылке: подписчиков - 628, экспертов - 148
В номере: вопросов - 1, ответов - 1

Нам очень важно Ваше мнение об этом выпуске рассылки. Вы можете оценить этот выпуск по пятибалльной шкале, пройдя по ссылке:
оценить выпуск >>

Вопрос № 169909: Пмогите решить задачку!!! Нужно написать стек таким образом, чтобы генерировать исключения для такого количества условий, какое Вы считаете приемлемым. (Например, невозможность выделить нужное количество памяти, переполнение стека и т.д.) Зара...



Вопрос № 169909:

Пмогите решить задачку!!!
Нужно написать стек таким образом, чтобы генерировать исключения для такого количества условий, какое Вы считаете приемлемым. (Например, невозможность выделить нужное количество памяти, переполнение стека и т.д.)
Заранее Спасибо!

Отправлен: 26.06.2009, 16:37
Вопрос задал: Руслан Радионович, Посетитель
Всего ответов: 1
Страница вопроса >>


Отвечает Micren, Практикант :
Здравствуйте, Руслан Радионович.

Программа. Тестировалась в MS VS 2008. Это важный момент. Т.к. далеко не во всех библиотеках class exception имеет конструктор с параметром const char* const.

Базовый класс для обработки исключений стека class stack_exception. Наследуйте от него свои классы исключений, если Вам мало тех, что уже есть.
Код:

#include <limits>
#include <locale>
#include <iostream>
#include <iomanip>
#include <stdexcept>

using namespace std;

// Базовый класс для исключений стека
class stack_exception:public exception
{
public:
stack_exception(const char* const msg="Исключен ие при работе со стеком")
:exception(msg)
{}
virtual ~stack_exception(){}
};

// Исключение при извлечении из пустого стека
class stack_empty_exception:public stack_exception
{
public:
stack_empty_exception(const char* const msg="Попытка извлечения из пустого стека")
:stack_exception(msg)
{}
};

// Исключение при возникновении переполнения стека
class stack_overflow_exception:public stack_exception
{
public:
stack_overflow_exception(const char* const msg="Стек переполнен")
:stack_exception(msg)
{}
};

class stack_iterator_exception:public stack_exception
{
public:
stack_iterator_exception(const char* const msg="Ошибка в итераторе")
:stack_exception(msg)
{}
};

// Класс-стек
template<class _Ty>
class stack
{
protected:
// Базовый класс для итератора. По заданию итераторы не требуются. Можно опустить.
class base_iterator
{
public:
_Ty& operator*()const
{
if(_current<_stack._top)
{
return _stack._data[_current];
}
throw stack_iterator_exception("Выход за границу стека");
}

bool operator==(const base_iterator& right) const
{
if(&_stack==right._stack)
{
return _current==right._current;
}
throw stack_iterator_exception("Итераторы служат для обработки разных стеков");
}
bool operator!=(const base_iterator& right) const
{
if(&_stack==&right._stack)
{
return _current!=right._current;
}
throw stack_iterator_exception("Итераторы служат для обработки разных стеков");
}
protected:
base_iterator(const stack<_Ty>& s,size_t current=0)
:_stack(s)
,_current(current)
{}
const stack<_Ty>& _stack;
size_t _current;
};
public:
// Итератор
class iterator:pu blic base_iterator
{
public:
const iterator& operator++()
{
if(_current<_stack._top)
{
++_current;
return *this;
}
throw stack_iterator_exception("Выход за границу стека");
}
const iterator operator++(int)
{
if(_current<_stack._top)
{
iterator res(*this);
++_current;
return res;
}
throw stack_iterator_exception("Выход за границу стека");
};
private:
iterator(const stack<_Ty>& s,size_t current=0)
:base_iterator(s,current)
{}
friend class stack;
};

// Методы и члены класса stack
// Конструктор
explicit stack(size_t size=_initSize);
stack(const stack& s);
// Деструктор
virtual ~stack(void);
// Оператор присваивания
const stack& operator=(const stack& right);
// Количество элементов в стеке
size_t count(void) const;
// Заносит данные в стек
void pus h(_Ty item);
// Извлекает элемент из стека
_Ty pop(void);
// Итератор на начало
iterator begin()
{
return iterato r(*this,0);
}
// Итератор на конец
iterator end()
{
return iterator(*this,_top);
}
private:
// Минимальный размер стека по умолчанию
static const size_t _initSize=32;
// Вершина стека
size_t _top;
// Размер стека
size_t _size;
// Данные стека
_Ty* _data;
// Освобождает ресурсы
void _dispose(void);
// Копирует данные
void _copy(const stack& s);
static void _copy(const _Ty* from, _Ty* to, size_t length);
friend class iterator;
friend class base_iterator;
};

// Печатает элементы стека. Используем для проверки.
template<class _Ty>
void printStack(stack<_Ty>& s)
{
for(stack<_Ty>::iterator it=s.begin();it!=s.end();++it)
{
cout<<*it<<',';
}
cout<<"\b \n";
}

int main()
{
setlocale(LC_ALL,"russian_russia");

try
{
stack<int> stack_1;
cout<<"П роверка метода push()"<<endl;
cout<<"В стек stack_1 заносятся следующие числа:"<<endl;
for(int i=0;i<10;++i)
{
cout<<i<<',';
stack_1.push(i);
}
cout<<"\b \n";
cout<<"Проверка итератора"<<endl;
cout<<"Были занесены следующие данные(в порядке попадания в стек):"<<endl;
printStack(stack_1);
cout<<"Проверка конструктора копирования"<<endl;
stack<int> stack_2(stack_1);
cout<<"stack_2(stack_1):"<<endl;
printStack(stack_2);
cout<<"Проверка оператора присваивания"<<endl;
stack<int> stack_3;
stack_3=stack_2;
cout<<"stack_3=stack_2:"<<endl;
printStack(stack_3);
cout<<"Проверка метода pop()"<<endl;
while(stack_3.count())
{
cout<<s tack_3.pop()<<',';
}
cout<<"\b \n";
}
catch(stack_exception ex)
{
cout<<ex.what()<<endl;
}
catch(bad_alloc)
{
cout<<"Ошибка выделения памяти"<<endl;
}
catch(...)
{
cout<<"Неизвестная ошибка"<<endl;
}
system("PAUSE");
return 0;
}

#pragma region Методы класса stack

// Конструктор специфицирующий начальный размер стека
template<class _Ty>
stack<_Ty>::stack(size_t size/* =32 */)
:_data(0)
,_top(0)
,_size(size)
{
if(_size<_initSize)
{
_size=_initSize;
}
_data=new _Ty[_size];
}

// Конструктор копирования
template<typename _Ty>
stack<_Ty>::stack(const stack& s)
:_data(0)
{
_copy(s);
}

// Оператор присваивания
template<typename _Ty>
const stack<_Ty>& stack<_Ty>::operator=(cons t stack& right)
{
if(this!=&right)
{
_copy(right);
}
return *this;
}

// Деструктор
template<typename _Ty>
stack<_Ty>::~stack(void)
{
_dispose();
}

// Количество элементов в стеке
template<typename _Ty>
size_t stack<_Ty>::count(void) const
{
return _top;
}

// Заносит данные в стек
template<typename _Ty>
void stack<_Ty>::push(_Ty item)
{
static const size_t _maxSize=numeric_limits<size_t>::max();
if(_top==_size)
{
if(_size==_maxSize)
{
throw stack_overflow_exception("Достигнут максимально возможный размер стека");
}
if(_size>(_maxSize>>1))
{
_size=_maxSize;
}
else
{
_size<<=1;
}
_Ty* newData=new _Ty[_size];
_copy(_data,newData,_top);
delete[] _data;
_data=newData;
}
_data[_top++]=item;
}

// Извлекает элемент из с тека
template<typename _Ty>
_Ty stack<_Ty>::pop(void)
{
if(_top)
{
return _data[--_top];
}
else< br> {
throw stack_empty_exception();
}
}

// Освобождает ресурсы
template<typename _Ty>
void stack<_Ty>::_dispose(void)
{
if(_data)
{
delete[] _data;
_data=0;
_size=_top=0;
}
}

// Копирует данные
template<typename _Ty>
void stack<_Ty>::_copy(const stack& s)
{
_dispose();

_size=s._size;
size_t length=_top=s._top;
_data=new _Ty[_size];

_copy(s._data,_data,_top);
}

template<typename _Ty>
void stack<_Ty>::_copy(const _Ty* from, _Ty* to, size_t length)
{
while(length--)
{
*to++=*from++;
}
}

#pragma endregion

Пример работы:
Код:

Проверка метода push()
В стек s tack_1 заносятся следующие числа:
0,1,2,3,4,5,6,7,8,9
Проверка итератора
Были занесены следующие данные(в порядке попадания в стек):
0,1,2,3,4,5,6,7,8,9
Проверка конструктора копирования
stack_2(stack_1):
0,1,2,3,4,5,6,7,8,9
Проверка оператора присваивания
stack_3=stack_2:
0,1,2,3,4,5,6,7,8,9
Проверка метода pop()
9,8,7,6,5,4,3,2,1,0

Ответ отправил: Micren, Практикант
Ответ отправлен: 28.06.2009, 05:55

Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 251571 на номер 1151 (Россия) | Еще номера >>
  • Отправить WebMoney:
  • Вам помогли? Пожалуйста, поблагодарите эксперта за это!



    Нам очень важно Ваше мнение об этом выпуске рассылки. Вы можете оценить этот выпуск по пятибалльной шкале, пройдя по ссылке:
    оценить выпуск >>

    подать вопрос экспертам этой рассылки >>

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров >>

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2009, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2009.6.3 от 20.06.2009

    В избранное