Re[6]: template для типа указателя в классе.
От: Al_ Россия нпкинтегра.рф
Дата: 22.09.03 00:29
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Ну да. А еще — вот это: 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>.

Я сразу понял к чему ты ведешь (:
Автоматизация.ERP
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.