У меня имеется класс "рассказ", который нужно хранить в различных сборниках. Суть в том, что я использую указатели, т.е.
class Story
{
...
}
class Compilation
{
...
vector
Необходимо изменять информацию о рассказах. Здесь всё ясно, поскольку мы храним указатели, то всё будет меняться параллельно. Удаление из конкретного сборника тоже ясно. Но если окажется, что этот сборник - последний, где хранится наш рассказ, то как произвести удаление без утечки памяти? Если же мы хотим удалить рассказ навсегда, то как его удалить из всех сборников сразу?
Хранить сборники внутри рассказа тоже не вариант, так как необходимо устраивать поиск по сборникам, количеству рассказов в них и т.д.
Ответ
Вам нужно пользоваться shared_ptr вместо сырого указателя. При этом ваш объект будет удалён только когда последний указатель на него умрёт.
Вот небольшой пример работы с ним
#include
class Story
{
int n;
public:
Story(int n): n(n) { cout << "story #" << n << " created" << endl; }
~Story() { cout << "story #" << n << " destroyed" << endl; }
};
int main()
{
vector
cout << "creating #1 and adding to first list" << endl;
list1.emplace_back(make_shared
Вывод:
creating #1 and adding to first list
story #1 created
copying #1 to second list
creating #2
story #2 created
adding #2 to the second list
removing first ptr to story #2
removing second ptr to story #2, now it will be destroyed
story #2 destroyed
clearing first list
clearing second list, now story #1 will be destroyed
story #1 destroyed
done
Как правильно подсказывает @ixSci в комментариях, вы таки можете удалить элемент полностью во всех списках, если примете немного другой дизайн. Поделим списки на владеющие своими элементами (эти списки будут содержать shared_ptr), и невладеющие (эти списки будут содержать weak_ptr, невладеющий указатель). Тогда когда все сильные ссылки (shared_ptr) на объект умрут, слабые (weak_ptr) тоже станут недействительны.
Этот оформляется так
#include
class Story
{
int n;
public:
Story(int n): n(n) { cout << "story #" << n << " created" << endl; }
~Story() { cout << "story #" << n << " destroyed" << endl; }
void print() { cout << "story #" << n << " reporting" << endl; }
};
int main()
{
vector
cout << "creating and adding to owning list" << endl;
main_list.emplace_back(make_shared
Вывод:
creating and adding to owning list
story #1 created
story #2 created
copying to non-owning list
removing #2
story #2 destroyed
story #1 reporting
(deleted entry)
cleaning non-owning list
story #1 reporting
done
story #1 destroyed
Комментариев нет:
Отправить комментарий