Как удалить шаблон? - PullRequest
       27

Как удалить шаблон?

0 голосов
/ 23 сентября 2010

У меня проблемы с удалением моего шаблона.
Мой шаблон и деструктор:

template<class S, class T>  
class Consortium
{

private :

    map<const S, Node<T>*> m_consortiumMap;
    Heap<T>m_consortiumHeap;

public :

    ~Consortium();
    void Insert(const S key, T toAdd);
    void Update(const S key);
    void Remove(const S key);
    const T Top();
};

template<class S, class T>
Consortium<S,T>::~Consortium()
{
    m_consortiumMap.clear();
    delete &m_consortiumHeap.;
}

Моя куча и деструктор:

template <class T>
class Heap
{
private :

    vector<Node<T>*> m_heapVector;

public :

    ~Heap();

    int parent(int i) const {return i / 2;}
    int left(int i) const {return 2 * i;}
    int right(int i) const {return 2 * i + 1;}
    void heapify(int index);
    Node<T>* extractMin ();
    void heapDecreaseKey (int index, Node<T>* key);
    void MinHeapInsert (Node<T>* key);
    Node<T>* ExtractNode(int index);
    Node<T>* top ()const {return m_heapVector[0];}

};  

template<class T>
Heap<T>::~Heap()
{
    for (int i = 0 ; i < m_heapVector.size() ; i++)
        m_heapVector.erase(m_heapVector.begin() + i);
}

, и это объект, которыйдержит шаблон, у меня тоже проблемы с этим:

class Garage
{
    private :

        Consortium<string, Vehicle*> m_consortium;

    public :

        ~Garage() {delete &m_consortium;}
};

что здесь не так?

Ответы [ 4 ]

2 голосов
/ 23 сентября 2010

Если вы не использовали new для создания объекта, вы не можете использовать delete, чтобы избавиться от него.

2 голосов
/ 23 сентября 2010

Это неправильно на его лице:

delete &m_consortiumHeap;

Вы должны только delete вещи, которые вы выделили с new.m_consortiumHeap является частью класса и автоматически выделяется, когда класс выделяется, и автоматически освобождается, когда класс освобождается.Вы не можете и не должны явно delete это.

Это может иметь противоположную проблему:

m_consortiumMap.clear();

содержимое m_consortiumMap является указателями.Я не могу сказать из кода, который вы показали, но если узлы в карте выделены классом Consortium с использованием new, они должны быть delete ed, иначе вы потеряете память.Очистка карты только избавит от указателей, она не освободит память, на которую они указывают.Сначала вы должны пройти по карте и delete каждый элемент.Хотя освобождение элементов важно, очистка карты в деструкторе бессмысленна, поскольку сама карта все равно будет уничтожена сразу после этого.

Это просто сбивает с толку:

for (int i = 0 ; i < m_heapVector.size() ; i++)
    m_heapVector.erase(m_heapVector.begin() + i);

firstвсе, что я сказал о m_consortiumMap, относится и к m_heapVector: если содержимое было выделено с new классом Heap, вы должны delete их в деструкторе.Стирание указателей из вектора бессмысленно, не говоря уже о том, что в цикле выше есть логическая ошибка.Когда вы перебираете контейнер, вы должны использовать сами итераторы, например,

for (std::vector<Node<T>*>::iterator i = m_heapVector.begin() ; i != m_heapVector.end() ; i++)

Кроме того, std::vector, как и std::map, имеет функцию clear(), но, как я сказал, очищать бессмысленновектор в деструкторе.Что вы действительно хотите сделать, так это освободить элементы (при необходимости).

1 голос
/ 23 сентября 2010

Вы, вероятно, хотите удалить объекты, на которые указывают элементы в векторе.Метод Erase не делает этого, он просто удаляет элемент указателя из вектора, не разрушая указанный объект.Поэтому вам нужно (я полагаю) сначала удалить указанный объект, чтобы избежать утечек памяти.Вы можете сделать это:

for( vector<Node<T>*>::iterator iter = m_heapVector.begin(), endI = m_heapVector.end(); iter != endI; ++iter)
{
   delete *iter;
}

// m_heapVector.clean(); // Not necessary in destructor, since the vector will be destroyed anyway.

Используя функции C ++ 0x:

std::for_each( m_heapVector.begin(), m_heapVector.end(), []( Node<T>* node) { delete node; });

Также используйте метод контейнера clear() (вектор в вашем случае), чтобы удалить всеэлементы.

0 голосов
/ 23 сентября 2010

Поскольку m_consortiumHeap является членом данных вашего класса (напрямую, а не указателем на него), вам не нужно явно удалять его. Когда экземпляр Консорциума уничтожается, он автоматически вызывает для вас деструктор m_consortiumHeap.

...