Пример за обектно ориентирана реализация на свързан стек.

19.Пример за обектно ориентирана реализация на свързан стек.

Ще се възпозлваме от тясната връзка свързани списъци <-> стекове при реализацията на класа на стековете, чрез повторното използване на шаблонния клас List. Ще предложим 2 разновидности на повторното използване.
Отначало – класа на стековете – чрез скрито наследяване класа на списъците. След това аналогично действащ клас на стековете чрез композиция.

По пътя на включването на класа на списъците като скрит елемент на класа на стековете.Двата класа стекове са шаблонни:

Файл: ”stack.h”

#ifndef _STACK_H_
#define _STACK_H_
 
#include ”list.h”
 
template < class STACK_TYPE >
class Stack:private List< STACK_TYPE >
{
    public:
        void push( const STACK_TYPE &d )
        {    insertAtFront( d );       }
 
        bool pop( STACK_TYPE &d )
        {    return removeFromFront( d );    }
        bool isStackEmpty()
        {    return isEmpty();    }
        void printStack()
        {    print();    }
 
};
 
#endif

Тук се създава шаблон на класа Stack чрез скрито наследяване на класа List. Необходимо е стекът да има член-функции push, pop, isEmptyStack, printStack. Те по същество са съответно член-функциите на шаблона на класа List: insertAtFront, removeFromFront, isEmpty, printStack. Шаблонът на List включва и други член-функции (например добавяне на елемент в края на списъка), които не искаме да правим достъпни чрез открития интерфейс на Stack. Това е причината да наследяваме private – правим всички член-функции на List закрити в шаблона Stack.
#include ”stack.h”
 
using std::endl;
 
void main()
{
// Шаблонът на класа се използа за реализация int Stack
    Stack<int> intStack;
    int popInteger, i;
    cout << “ Обработка на стека с цели числа.. ” « endl;
    for (i = 0; i < 4; i++)
    {
        intStack.push (i);
        intStack.printStack ();
    }
    while ( !intStack.isStackEmpty() )
    {
        intStack.pop (popInteger);
        cout << popInteger << “ е изключено от стека!” << endl;
        intStack.printStack ();
    }
 
// Шаблонът на класа се използа за реализация double Stack
    Stack <double> doubleStack;
      double value = 1.1, popDouble;
    cout << “Обработка на стек с числа с плаваща точка” << endl;
    for (i = 0; i < 4; i++)
     {
        doubleStack.push (value);
        doubleStack.printStack ();
        value += 1.1;
    }
    while (!doubleStack.isStackEmpty())
     {
        doubleStack.pop ( popDouble );
        cout << popDouble << “ е изключено от стека!” << endl;
        doubleStack.printStack ();
    }
}

Друг начин за реализиране на шаблона на класа Stack е повторното използване на шаблона на класа List чрез композиция( влагане на обект в друг).

Файл: ”stack-compose.h”

#ifndef _STACK_COMPOSE_H_
#define _STACK_COMPOSE_H_
 
#include ”list.h”
 
template < class STACK_TYPE >
class Stack
{
    public:
        void push( const STACK_TYPE &d )
        {    s.insertAtFront( d );       }
 
        bool pop( STACK_TYPE &d )
        {    return s.removeFromFront( d );    }
        bool isStackEmpty()
        {    return s.isEmpty();    }
        void printStack()
        {    s.print();        }
 
    private:
        List<STACK_TYPE> s;
};
 
#endif

Дефинирането на шаблона на класа Stack включва обекта s от класа List<STACK_TYPE>. Тук ще използва същата програма за тестване с тази разлика, че ще включи новия заглавен файл stack-compose.h сместо stack.h. Резултатът от изпълнението е същият.

Напомняме, че реализациите почиват върху различна логика:
Тема 18 – указател към указател
Тема 19 – Stack чрез List
Тема 22, 23 се използва свързан стек, но друга директна реализация на класа ( процедурна, чрез шаблона на списъците и директна реализация на стек )

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License