Подтвердить что ты не робот

Ли вектор:: erase() на векторе указателей объектов уничтожает сам объект?

У меня есть вектор указателей на объекты. Мне нужно удалить элемент из вектора и поместить этот элемент в другой список.

Я читал, что стирание может быть использовано для удаления объекта из вектора, но я также прочитал, что он вызывает деструктор объектов, прежде чем это делать.

Мне нужно знать, уничтожит ли этот объект или нет.

4b9b3361

Ответ 1

vector::erase
Удаляет из векторного контейнера и вызывает его деструктор, но если содержащийся объект является указателем, он не принимает на себя ответственность за его уничтожение.

Вам нужно будет явно вызвать delete для каждого содержащегося указателя для удаления содержимого, на которое оно указывает, например:

void clearVectorContents( std::vector <YourClass*> & a ) 
{    
    for ( int i = 0; i < a.size(); i++ ) 
    {       
        delete a[i];    
    }    
    a.clear(); 
} 

Хранение исходных указателей в стандартных контейнерах не является хорошей идеей. Если вам действительно нужно сохранить ресурсы, которые должны быть выделены new, тогда вы должны использовать boost::shared_ptr. Ознакомьтесь с Документация Boost.

Более общее и элегантное решение:
Это решение использует for_each и templates, как @Billy указал в комментариях:

// Functor for deleting pointers in vector.
template<class T> class DeleteVector
{
    public:
    // Overloaded () operator.
    // This will be called by for_each() function.
    bool operator()(T x) const
    {
        // Delete pointer.
        delete x;
        return true;
    }
};

И это можно назвать:

for_each( myclassVector.begin(),myclassVector.end(),
          DeleteVector<myclass*>());

где myclassVector - ваш вектор, содержащий указатели на объекты класса myclass.

Пример использования:

#include "functional"
#include "vector"
#include "algorithm"
#include "iostream"

//Your class
class myclass
{
    public:
        int i;
        myclass():i(10){}
};


// Functor for deleting pointers in vector.
template<class T> class DeleteVector
{
    public:
    // Overloaded () operator.
    // This will be called by for_each() function.
    bool operator()(T x) const
    {
        // Delete pointer.
        delete x;
        return true;
    }
};


int main()
{
    // Add 10 objects to the vector.
    std::vector<myclass*> myclassVector;

    for( int Index = 0; Index < 10; ++Index )
    {
        myclassVector.push_back( new myclass);
    }

    for (int i=0; i<myclassVector.size(); i++) 
    {
        std::cout << " " << (myclassVector[i])->i;
    }

    // Now delete the vector contents in a single  line.
    for_each( myclassVector.begin(),
              myclassVector.end(),
              DeleteVector<myclass*>());

    //Clear the vector 
    myclassVector.clear();

    std::cout<<"\n"<<myclassVector.size();

    return 0;
}

Ответ 2

  • Если у вас есть vector<MyObject>, тогда MyObject::~MyObject будет называется.
  • Если у вас есть vector<MyObject*>, то delete <MyObject instance> не будет вызываться.

Чтобы переместить MyObject между двумя векторами, вам нужно сначала вставить его в целевой вектор, а затем стереть оригинал. Обратите внимание, что это создаст новую копию объекта. При перемещении указателей вы можете просто сохранить указатель во временной переменной, удалить его из вектора, а затем вставить туда, где вам нужно.

И вот еще один простой способ удалить, а затем удалить все элементы в векторе:

template<class T> void purge( std::vector<T> & v ) {
    for ( auto item : v ) delete item;
    v.clear();
}

Ответ 3

Да, конечно. Если объект не существует в векторе, где еще он существовал бы?

Изменить: это не приведет к удалению указателя. Для управления временем жизни объекта следует использовать автоматические указатели управления временем жизни, такие как shared_ptr.

Ответ 4

Да, erase уничтожает элемент. Однако, если вы помещаете элемент в другой контейнер, вы, вероятно, сделали копию, помещенную в этот другой контейнер. Единственный способ, которым вы столкнулись с проблемами, - это скопировать указатель или что-то подобное в другой контейнер.

Ответ 5

Да. vector::erase уничтожает удаленный объект, который включает вызов его деструктора.