Здравствуйте, Кодт, Вы писали:
К>Ну да. А еще — вот это: i=*(quInt.GetItem()); Я так понимаю — это мы выпихиваем элемент из очереди, следовательно, прекращаем владение данными, на которые ссылается указатель.
Неа. Он просто возвращает Смотри класс ниже.
template <class Tm>
Tm CQueue<Tm>::DataByPosition(DWORD dwPos)
{
TT pDat;
PushChoiser();
ChoiseItems();
for (DWORD i=0; i<dwPos; i++)
pDat = SelectNextDataFromChoise();
PopChoiser();
return pDat;
}
К> После разыменования мы копируем данные в переменную, а что делаем с оригиналом? Если это был new int(5) — получаем утечку памяти.
Нет никакой утечки. GetItem() всего лишь
получает, допустим, текущий элемент, либо по позиции: GetItem(DWORD dwPos=0) (в моем классе таких методов нет вообще
-прим), которая ищется перебором.
Удаление элемента выполняет другой метод, допустим DeleteItem(DWORD dwPos=0).
Утечки нет! (%
Думаю надо привести мой класс для критики (:
template <class T>
class CQueueItem // КЛАСС: структура очереди.
{
CQueueItem<T> *pPrevItem, *pNextItem;
public:
T pData; // Значение элемента очереди
CQueueItem(T Data);
CQueueItem();
virtual ~CQueueItem();
};
template <class TT = CObject*>
class CQueue // КЛАСС: очередь объектов типа ТТ
{
BOOL KeepEqualItems; // Определяет будет ли хранить экземпляр
// класса элементы с одинаковым значением
CQueue<CQueueItem<TT>*> *pChoiserStek;
CQueueItem<TT> *pChoiser; // Текущий элемент выборки
public:
CQueue();
CQueue(TT Data);
~CQueue();
SetKeepEqualFlag(BOOL);
CQueueItem<TT> *FirstItem; // Первый элемент очереди
CQueueItem<TT> *LastItem; // Послед элемент очереди
// Добавляет новый элемент, возвращает его указатель
CQueueItem<TT> *AddItemToEnd(TT Data);
void AppendQueue(CQueue<TT> *pQueue); // Добавляет очередь элементов
void Append2Queue(CQueue<TT> **pQueue); // Добавляется к очереди элементов
void SubtractQueue(CQueue<TT> *pQueue); // Удаляет из очереди элементы очереди pQueue
void ChoiseItems(); // Инициализации выборки
CQueueItem<TT> *SelectNextFromChoise(); // Возвращает следующий элемент из выборки
TT SelectNextDataFromChoise(); // Возвращает следующее значение из выборки
TT DataByPosition(DWORD dwPos);
CQueueItem<TT> *FindByData(TT Data);
CQueueItem<TT> *FindByData(TT Data, DWORD *Pos);
BOOL CompareWithQueue(CQueue<TT> *pQueue); // Сравнивает с очередью (1-equal)
void DeleteItem(CQueueItem<TT> *pItem);
CQueueItem<TT> *DeleteItem(TT Data);
void EmptyQueue();
void PushChoiser();
BOOL PopChoiser();
DWORD QueueLen();
SaveToFile(HFILE hFl);
LoadFromFile(HFILE hFl);
};
К>>>Так ты разнесешь функциональность очереди вообще и специфики указателей.
Al_>>А для этого разве недостаточено просто написать в деструкторе CQueueItem: delete pData
? (pData определен в этом классе как TT pData). При этом если TT будет классом, то вызовется его деструктор.
К>Не только недостаточно, но и избыточно!!! CQueueItem разрушается в ходе выполнения GetItem().
Как я уже говорил никто там не разрушается, там все только получается/возвращается (%
К> Спрашивается: что мы вернем оттуда — висячий указатель на свежеубитый объект?
Ну если удалять — то да.
К>А с другой стороны, если мы хотим просто выпихнуть элемент из очереди... Нужно писать delete theQueue.GetItem();
Для этого у меня есть методы CQueue::DeleteItem() — они удаляют элементы либо по позиции (Параметр CQueueItem*) либо по значению (параметр TT). В последнем случае перебираются элементы очереди и удаляется элемент, который хранит в себе искомое значение.
К>Чтобы не забивать голову с управлением — нужно хранить в очереди умные указатели std::auto_ptr<T>, boost::shared_ptr<T>, Loki::SmartPtr<T>.
Я сразу понял к чему ты ведешь (: