template <class T> class PACKAGE TtStack:
{
//DONE -oСтек значений -cКласс: Класс шаблона стека
public:
template <class T> struct TtItem
{
TtItem <T> *Prev, *Next; // Указатели на предыдущий и следующий элементы
T Value; // Значение элемента
inline __fastcall TtItem (void): Value (T()), Prev (NULL), Next (NULL)
{}
};
typedef TtStack <T> TcStack;
private:
int _fCount; // Кол-во элементов
TtItem<T> *_fFirst, *_fLast; // Указатели на первый и последний элементы
inline const T& __fastcall Get_Item (void) const
{this->Test_Last(); return _fLast->Value;}
inline const TtItem<T>* __fastcall Get_First (void) const
{this->Test_First(); return _fFirst;}
inline const TtItem<T>* __fastcall Get_Last (void) const
{this->Test_Last(); return _fLast;}
inline void __fastcall Set_Item (const T &Value)
{this->Test_Last(); _fLast->Value = Value;}
protected:
void inline __fastcall Test_Count (int Index) const;
void inline __fastcall Test_First (void) const;
bool inline __fastcall Test_Index (int Index) const;
void inline __fastcall Test_Last (void) const;
__property TtItem<T>* _pFirst = {read = _fFirst};
__property TtItem<T>* _pLast = {read = _fLast};
public:
virtual __fastcall ~TtStack (void);
inline __fastcall TtStack (void);
inline __fastcall TtStack (const TtStack<T> &Other);
virtual void __fastcall Clear (void); // Очистка стека
inline T& __fastcall Edit (void); // Чтение изменяемого последнего значения
virtual void __fastcall Pop (void); // Удаление последнего значения
virtual inline void __fastcall Pop (T &Value) // Чтение с удалением последнего значения
{Value = this->Last->Value; this->Pop();}
virtual void __fastcall Pull (void); // Удаление первого значения
virtual inline void __fastcall Pull (T &Value) Чтение с удалением первого значения
{Value = this->First->Value; this->Pop();}
virtual void __fastcall Push (void); // Добавление нового значения
virtual inline void __fastcall Push (const T &Value) // Добавление указанного значения
{this->Push(); _fLast->Value = Value;}
__property int Count = {read = _fCount};
__property T Item = {read = Get_Item, write = Set_Item};
__property const TtItem<T>* First = {read = Get_First};
__property const TtItem<T>* Last = {read = Get_Last};
};
//---------------------------------------------------------------------------
Создание класса группы объектов
Нужно создать что-то типа стека объектов, но так ,что бы туда можно было вставлять любой объект. Вроде стандартная задача, но пока плохо я в шаблонах разбираюсь и не могу понять как это сделать.Через void* не подходит - слишком примитивно.Как - нибудь это можно сделать через Iterator или еще как - нибудь?
Исспользуй его вместо void *
А какие есть еще варианты?
Объекты должны быть однотипными? Я для такой цели создал свой шаблон
Объекты должны быть не однотипными, а иметь общий интерфейс, например, как IUnknown.
Тогда в стек будут помещаться не объекты, а указатели на них. И код можно будет написать по-проще
Код:
template <T> class TStack_Ptr
{
private:
typedef TStack_Ptr<T> Tthis; // Переопределение типа класса реализации
[INDENT]int _fCount; // Кол-во доступных элементов
int _fIndex; // Кол-во используемых элементов
T *_fCurrent; // Указатель на текущий элемент
T **_fPointers; // Указатель на массив указателей
Tthis& operator = (const Tthis &Other)
{} // Блокировка оператора присваивания
TStack_Ptr (const Tthis &Other)
{} // Блокировка конструктора копирования
void Grow (void) // Увеличение размера массива под указатели
{_fPointers = (T**) realloc (_fPointers, _fCount += 16); }
void Test_Current (void) const // Проверка наличия хоть одного эл-та в стеке
{if (_fIndex == 0) throw EAccessViolation ("Объекты отсутствуют");}
[/INDENT]public:[INDENT]// Приведение последнего эл-та к указателю на объект
operator T* (void)
{this->Test_Current(); return _fCurrent;}
operator const T* (void) const
{this->Test_Current(); return _fCurrent;}
T* operator -> (void)
{this->Test_Current(); return _fCurrent;}
const T* operator -> (void) const
{this->Test_Current(); return _fCurrent;}
virtual ~TStack_Ptr (void)
{ // Деструктор[INDENT] for (; _fIndex > 0; _fCurrent = _fPointers [--_fIndex])
delete _fCurrent;
free (_fPointers);
[/INDENT]}
TStack_Ptr (void): _fCount (16), _fIndex (0), _fCurrent (NULL)
{ // Конструктор по умолчанию[INDENT]_fPointers = (T**) malloc (_fCount * sizeof (T*)); // Создание массива указателей
_fPointers[0] = NULL; // Обнуление нулевого элемента - зарезервирован
[/INDENT]}
int Push (T *New_Ptr)
{ // Добавление указателя в список[INDENT]if (_fIndex == _fCount) // Увеличение массива при необходимости
this->Grow();
_fPointers [_fIndex++] = _fCurrent = New_Ptr;
[/INDENT]}
T* Pop (void)
{ // Извлечение указателя из списка[INDENT]this->Test_Current();
T *Res = _fCurrent;
_fCurrent = _fPointers [--_fIndex];
[/INDENT]}
virtual void Delete (void)
{ // Удаление текущего элемента[INDENT] if (_fIndex > 0)
{
delete _fCurrent;
_fCurrent = _fPointers [--_fIndex];
}
[/INDENT]}
virtual void Clear (void)
{ // Очистка стека, уменьшение массива указателей[INDENT] for (; _fIndex > 0; _fCurrent = _fPointers [--_fIndex])
delete _fCurrent;
_fPointers = (T**) realloc (_fPointers, _fCount = 16);
[/INDENT]}
__property Items = {read = _fIndex}; // Чтение кол-ва помещённых элементов
[/INDENT]};
{
private:
typedef TStack_Ptr<T> Tthis; // Переопределение типа класса реализации
[INDENT]int _fCount; // Кол-во доступных элементов
int _fIndex; // Кол-во используемых элементов
T *_fCurrent; // Указатель на текущий элемент
T **_fPointers; // Указатель на массив указателей
Tthis& operator = (const Tthis &Other)
{} // Блокировка оператора присваивания
TStack_Ptr (const Tthis &Other)
{} // Блокировка конструктора копирования
void Grow (void) // Увеличение размера массива под указатели
{_fPointers = (T**) realloc (_fPointers, _fCount += 16); }
void Test_Current (void) const // Проверка наличия хоть одного эл-та в стеке
{if (_fIndex == 0) throw EAccessViolation ("Объекты отсутствуют");}
[/INDENT]public:[INDENT]// Приведение последнего эл-та к указателю на объект
operator T* (void)
{this->Test_Current(); return _fCurrent;}
operator const T* (void) const
{this->Test_Current(); return _fCurrent;}
T* operator -> (void)
{this->Test_Current(); return _fCurrent;}
const T* operator -> (void) const
{this->Test_Current(); return _fCurrent;}
virtual ~TStack_Ptr (void)
{ // Деструктор[INDENT] for (; _fIndex > 0; _fCurrent = _fPointers [--_fIndex])
delete _fCurrent;
free (_fPointers);
[/INDENT]}
TStack_Ptr (void): _fCount (16), _fIndex (0), _fCurrent (NULL)
{ // Конструктор по умолчанию[INDENT]_fPointers = (T**) malloc (_fCount * sizeof (T*)); // Создание массива указателей
_fPointers[0] = NULL; // Обнуление нулевого элемента - зарезервирован
[/INDENT]}
int Push (T *New_Ptr)
{ // Добавление указателя в список[INDENT]if (_fIndex == _fCount) // Увеличение массива при необходимости
this->Grow();
_fPointers [_fIndex++] = _fCurrent = New_Ptr;
[/INDENT]}
T* Pop (void)
{ // Извлечение указателя из списка[INDENT]this->Test_Current();
T *Res = _fCurrent;
_fCurrent = _fPointers [--_fIndex];
[/INDENT]}
virtual void Delete (void)
{ // Удаление текущего элемента[INDENT] if (_fIndex > 0)
{
delete _fCurrent;
_fCurrent = _fPointers [--_fIndex];
}
[/INDENT]}
virtual void Clear (void)
{ // Очистка стека, уменьшение массива указателей[INDENT] for (; _fIndex > 0; _fCurrent = _fPointers [--_fIndex])
delete _fCurrent;
_fPointers = (T**) realloc (_fPointers, _fCount = 16);
[/INDENT]}
__property Items = {read = _fIndex}; // Чтение кол-ва помещённых элементов
[/INDENT]};
Создание объектов должно производиться в программе.
При извлечении указателей (Pop), удаление объектов должно производиться в программе
Методы Delete и Clear производят удаление объектов, также объекты будут удалены деструктором.