2016-04-08 5 views
1
#include <vector> 
#include <iostream> 
#include <memory> 
using namespace std; 
class Test 
{ 
    public: 
    Test(){ cout<<"Const\n"; } 
    ~Test(){ cout<<"Dest\n"; } 
}; 
int main() 
{ 
    vector<Test *> tVec; 
    tVec.push_back(new Test()); 
    tVec.push_back(new Test()); 
    tVec.insert(tVec.end(),new Test()); 
    tVec.emplace(tVec.end(),new Test[4]); 
    vector<Test *>::iterator it; 
    for(it = tVec.begin(); it != tVec.end(); it++) 
    { 
     delete *it; 
     it = tVec.erase(it); 
    } 
    return 0; 
} 

ВЫВОД:Проблема в удалении отдельных элементов вектора в C++

Const Const Const Const Const Const Const Dest Dest

только два деструктор был вызван, а 8 - конструктор. Я знаю последние четыре объекта, которые я создал как массив. Есть ли общий способ удаления отдельных объектов внутри вектора. Второй Как получить доступ к этому отдельному элементу массива.

+3

для 'new []' вам нужно вызвать 'delete []' вы не можете обойти это, поэтому поверните каждый указатель в указатель на массив (например, 'vector >') или у вас есть два вектора – BeyelerStudios

+0

, почему вы храните указатели в векторе? Тот факт, что вы хотите удалить их вручную, указывает, что вам действительно не нужны указатели (вам понадобятся указатели, если объекты принадлежат кому-то другому, и в этом случае вектор не хочет их удалять). – user463035818

ответ

3

(Формально поведение вашей программы неопределенными: вы должны никогда смесь new[] с delete:. Каждый new должны быть сбалансированы с delete, и каждый new[] сбалансирован с delete[])

Взаимодействие it = tVec.erase(it); с it++ в цикле for дает вам gyp. (Итератор возвращается eraseуже следующий).

Вы пропускаете любой другой векторный элемент.

Удалите инструкцию инкремента из цикла for (мой предпочтительный выбор), и все будет хорошо.

Что касается общих образом, если вы должны были использовать std::vector<std::unique_ptr<Test>> вместо этого, то значительно проще и надежнее tVec.clear() будет делать эту работу. Или используйте std::vector<Test> и используйте (i) размещение и (ii) доверяйте своему компилятору, чтобы исключить любые копии значений.

+1

Но, как сказал @BeyelerStudios, вам все равно нужно обработать массив ... Я проголосую за std :: unique_ptr – Ceros

+0

Для массивов простым способом было бы использовать std :: shared_ptr и при необходимости предоставлять произвольный отладчик массива (shared_ptr удерживает делетитель). – axalis

1

Вот версия, которая будет действительно назвать все деструкторы включая массивы:

void ArrayDeleter(Test *t) { 
    delete[] t; 
}; 

int main() 
{ 
    vector<shared_ptr<Test> > tVec; 
    tVec.push_back(make_shared<Test>()); 
    tVec.push_back(make_shared<Test>()); 
    tVec.insert(tVec.end(), make_shared<Test>()); 
    tVec.emplace(tVec.end(), shared_ptr<Test>(new Test[4], ArrayDeleter)); 
    tVec.clear(); 
    return 0; 
} 

Тем не менее, ArrayDeleter должен быть передан в явном виде, в противном случае он не будет работать на самом деле.

 Смежные вопросы

  • Нет связанных вопросов^_^