Контейнеры STL, удалить объект из двух контейнеров - PullRequest
3 голосов
/ 19 августа 2010

Предположим, у меня есть два контейнера, в которых содержатся указатели на объекты, которые имеют некоторые общие элементы. от http://www.cplusplus.com/reference/stl/list/erase/ это говорит о том, что:

Это эффективно уменьшает размер списка по количеству удаленных элементов, вызывая деструктор каждого элемента до этого.

Как удалить объект из обоих контейнеров, не вызывая деструктор дважды:

Пример

#include <map>
#include <string>
using namespace std;
//to lazy to write a class 
struct myObj{
          string pkid;
          string data;
};
map<string,*myObj> container1;
map<string,*myObj> container2;

int main()
{
       myObj * object = new myObj();
       object->pkid="12345";
       object->data="someData";
       container1.insert(object->pkid,object);
       container2.insert(object->pkid,object);

       //removing object from container1
       container1.erase(object->pkid);
       //object descructor been called and container2 now hold invalid pointer

       //this will call try to deallocate an deallocated memory
       container2.erase(object->pkid);

}

пожалуйста, совет

Ответы [ 2 ]

4 голосов
/ 19 августа 2010

Если ваши контейнеры содержат указатели, то деструктор для этих объектов не будет вызываться (STL не будет следовать за этими указателями и вызывать деструктор объекта).

И наоборот, если ваши контейнеры удерживалисамих полноразмерных объектов, тогда будет вызван деструктор для этих объектов.

У вас также были некоторые синтаксические ошибки в объявлении карты и операторах вставки.Попробуйте запустить следующий код.Обратите внимание, что деструктор вызывается только один раз (для оператора delete). Деструктор никогда не вызывается для операторов стирания .

#include <map>
#include <string>
#include <iostream>
using namespace std;
//to lazy to write a class 
struct myObj{
    ~myObj() {
        cout << "DESTRUCTION" << endl;
    }
          string pkid;
          string data;
};
map<string,myObj*> container1;
map<string,myObj*> container2;

int main()
{
       myObj * object = new myObj();
       object->pkid="12345";
       object->data="someData";
       container1.insert(pair<string,myObj*>(object->pkid,object));
       container2.insert(pair<string,myObj*>(object->pkid,object));

       //removing POINTER from container1
       container1.erase(object->pkid);
       //object's destructor has NOT been called yet

       //removing POINTER from container2
       container2.erase(object->pkid);
       //object's destructor STILL hasn't been called

       delete object;   // DESTRUCTION!
}
3 голосов
/ 19 августа 2010

Используйте счетчики ссылок, чтобы определить, все ли ваши контейнеры удалили ваш объект. Boost имеет счетчик ссылок класса shared_ptr.

http://www.boost.org/doc/libs/1_44_0/libs/smart_ptr/shared_ptr.htm

...