Шаблон класса односвязной очереди.

В свое время изучая все богатство возможностей библиотеки STL и, применяя эти возможности на практике, обнаружил, что основным необходимым мне контейнером является односвязная очередь типа FIFO - "первым зашел - первым вышел". Видимо это связано со спецификой разрабатываемых программ - взаимодействие с различными внешними устройствами, также разработанных нашей фирмой. Обмен ведется сообщениями через последовательные интерфейсы - COM, USB, протокол TCP/IP. В одной из своих программ насчитал 27 очередей под различные типы данных.

Такого контейнера - односвязной очереди типа FIFO, в библиотеке STL не существует. Есть удобный адаптер под стандартные типы контейнеров STL. Но! Вот всегда это самое но и в самых неожиданных местах! Практика научила, что использовать библиотеку STL следует с определенной долей осторожности. Реализации библиотеки отличаются в зависимости от компилятора. Например некоторые реализации подразумевают потоковую безопасность, некоторые нет. По мне, так потоковую безопасность легче организовать программисту на прикладном уровне. Тем более если в ней нет необходимости, а в Вашей реализации она существует, то это просто ведет к увеличению накладных расходов. Я могу привести еще много примеров подобного типа, но ни в коем случае не отговариваю Вас от изучения и применения библиотеки STL. Просто при использовании следует тщательно изучить реализацию библиотеки и обязательно протестировать фрагменты кода, где эта библиотека применяется. В моем случае пришла мысль о написании простого, компактного шаблона односвязной очереди, что называется "без всяких затей". Листинг шаблона приводится ниже:

/---------------------------------------------------------------------------
#ifndef PQueueH
#define PQueueH
//---------------------------------------------------------------------------
// Структура определяющая узел очереди.
template <class T>
struct QueueNode {
T data;
QueueNode * next;
QueueNode() { next = 0; }
};
//---------------------------------------------------------------------------
// Темплетный универсальный класс очереди.
template <class Q>
class TPQueue {
private:
QueueNode<Q> * BeginQ, * LastQ;
// Счетчик объектов в очереди.
long count;
public:
TPQueue();
~TPQueue();
bool PutQueue(Q data);
bool CheckQueue();
Q GetQueue();
bool ClearQueue();
long size() { return count; }
};
//---------------------------------------------------------------------------
// Конструктор.
template <class Q>
TPQueue<Q> :: TPQueue() {
BeginQ = 0;
LastQ = 0;
count = 0;
}
//---------------------------------------------------------------------------
// Деструктор - освобождаем очередь и память выделенную под объекты.
template <class Q>
TPQueue<Q> :: ~TPQueue() {
QueueNode<Q> * work;

while(BeginQ) {
work = BeginQ->next;
delete BeginQ;
BeginQ = work;
}
BeginQ = 0;
LastQ = 0;
count = 0;
}
//---------------------------------------------------------------------------
// Положить в очередь.
template <class Q>
bool TPQueue <Q> :: PutQueue(Q data) {
QueueNode<Q> * link = new QueueNode<Q>;

count++;
if(!BeginQ) {
link->data = data;
BeginQ = link;
LastQ = link;
}
else {
link->data = data;
LastQ->next = link;
LastQ = LastQ->next;
}
return true;
}
//---------------------------------------------------------------------------
// Проверить состояние очереди.
template <class Q>
bool TPQueue <Q> :: CheckQueue() {
if(BeginQ) return true;
else return false;
}
//---------------------------------------------------------------------------
// Изъять из очереди.
template <class Q>
Q TPQueue <Q> :: GetQueue() {
QueueNode<Q> * link;
Q p;

if(BeginQ) {
count--;
link = BeginQ;
BeginQ = BeginQ->next;
if(!BeginQ) LastQ = 0;
p = link->data;
delete link;
return p;
}
else return 0;
}
//---------------------------------------------------------------------------
// Очистить очередь.
template <class Q>
bool TPQueue <Q> :: ClearQueue() {
QueueNode<Q> * link;

while(BeginQ) {
link = BeginQ;
BeginQ = BeginQ->next;
if(!BeginQ) LastQ = 0;
delete link;
}
count = 0;
return true;
}
//---------------------------------------------------------------------------
#endif // PQueueH


Текст листинга достаточно прост и не требует комментариев.

Пример использования - 2 очереди, первая для типа int, вторая для AnsiString. Компилятор Builder C++ 6.

Ссылка - myFIFO.rar

Шаблон содержится в файле PQueue.h.


Copyright © 2002
Created by Veacheslav Movila E-mail: Web-design
Хостинг от uCoz