Пример: Класс, описывающий базовый класс списка и производный класс стека
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <assert.h>
using namespace std;
// класс, описывающий один узел :
class ListItem
{
int data;
ListItem *next, *prev;
friend class List;
friend class Stack;
int Get() { return data; }
friend ostream& operator << (ostream&, List*);
friend istream& operator >> (istream&, List*);
public:
ListItem(const int d) // конструктор
{
data = d;
next = prev = NULL;
}
};
// Базовый класс списка:
class List
{
protected:
ListItem *back, *front, *token;
friend ostream & operator<<(ostream&, List*);
friend istream & operator>>(istream&, List*);
public:
List() {back = front = token = NULL;}
~List();
void PutToken(int); // добавляет элемент в список
virtual int GetToken(); // считывает текущий элемент списка
BOOL empty() {return front == NULL ? true:false;}
};
//Производный класс:
class Stack: public List
{
/* Стек является частным случаем списка и отличается главным образом тем, что удаление данных выполняется с конца. Будем считать, что при чтении данных стека, элементы данных удаляются (чтение с разрушением) */
int GetToken(); //считывает данные из стека
};
//---------------------------------------------------------------
//определение функций:
void List :: PutToken(int val)
{
ListItem *p = new ListItem(val);
if(empty()) front=back=p;
else
{
back->next = p; p->prev=back; back=p;
}
}
//----------------------------------------------------
int List :: GetToken()
{
if (token == NULL) token = front;
if (token)
{
int rv = token->data;
token = token->next;
return rv;
}
else return 0;
}
//---------------------------------------------------
ostream& operator << (ostream& os, List* q)
{
os<<"< ";
do
if (! q->empty())
os << q->GetToken() << ",";
while (q->token);
return os << ">" << endl;
}
//----------------------------------------------------------
istream & operator >> (istream &is, List* q)
{
int a; int k;
cout<<"Сколько элементов будете вводить? ";
is>>k;
for(int i=0; i<k; i++)
{
cout << i+1 << ": "; is >> a;
q->PutToken(a);
}
return is;
}
int Stack :: GetToken()
//Удаляет элемент c конца списка
{
if (token == NULL) token = back;
if (back)
{
back = back->prev; //Следующий элемент становится первым
if (back)
{ back->next = NULL; }
else front = NULL;
int retval = token->data;
delete token;
token = back;
return retval;
}
else return 0;
}
//--------------------------------------------------------------
int main()
{
//Настройки шрифтов и региональных стандартов:
if(SetConsoleCP(1251)==0)
//проверка правильности установки кодировки символов для ввода
{
cerr<<"Fialed to set codepage!"<<endl;
/* если не удалось установить кодовую страницу, вывод сообщения об ошибке */
}
if(SetConsoleOutputCP(1251)==0)//тоже самое для вывода
{
cerr<<"Failed to set OUTPUT page!"<<endl;
}
List* lst = new List;
cin >> lst;
cout<<"Список:\n";
cout << lst;
cout<<"Повторный вывод списка:\n";
cout << lst;
List* st; // Обратите внимание на тип указателя
st = new Stack;
cin >> st;
cout<<"Стек:\n";
cout << st; //Удаляет элемент c "хвоста"
cout<<"Повторный вывод стека:\n";
cout << st; // стек уже пуст
_getch();
return 0;
}