Игры здесь
Вторник, 25.07.2017, 09:33



Приветствую Вас Гость | RSS
[ Главная ] [ STL и Boost: сравнение контейнеров list, vector, ... - Форум ] [ Регистрация ] [ Вход ]
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 11
Форум » Разработка ПО и игр » С++, STL, Boost и все все все » STL и Boost: сравнение контейнеров list, vector, ...
STL и Boost: сравнение контейнеров list, vector, ...
DoubleVenomДата: Понедельник, 21.02.2011, 15:16 | Сообщение # 1
Рядовой
Группа: Администраторы
Сообщений: 12
Репутация: 0
Статус: Offline
std::list<s> при push_back(s) копирует s посредством конструктора копирования(!) (по удалении списка вызывается деструктор каждого элемента). Сам list реализован через указатели как пишут в справочниках.
Логичнее исп-ть std::list<s*>, тогда не происходит копирование s, но с ним сложно работать с памятью, т.к. десрукторы придется вызывать вручную при удалении элементов и самого списка.
Поэтому лучше исп-ть boost::ptr_list<s>. Он автоматом вставляет объекты через ptr_list::push_back(*s). Происходит копирование указателя, а не объекта. В нем удаление происходит автоматически при исчезновении ссылки на s. (erase(iterator) & удаление списка происходит с полным удалением содержимого)

Пример:
//testString наследует от string и выводит отладочные сообщения о том, что вызван конструктор/деструктор

1) Вариант с list<T*>:

struct DocObject {
public:
list<testString*> attrMapNames; //объявление списка указателей
public:
DocObject() {
attrMapNames.push_back(new testString("general")); //добавление элемента "general"; короткий способ
testString *s = new testString("additional");
attrMapNames.push_back(s); //способ с вспомогательной переменной типа указатель s
}
};

int main(int argc, char *argv[])
{
DocObject *dObj = new DocObject;

delete dObj;

return EXIT_SUCCESS;
}

__________
Программа выводит след.:

testString constructor called
testString constructor called
__________

Как видим, деструктор не вызван ни разу!

2) Вариант с ptr_list<T>:

struct DocObject {
public:
ptr_list<testString> attrMapNames; //обратите внимание, testString объявляется без '*'
public:
DocObject() { //код аналогичен вышеуказанному
attrMapNames.push_back(new testString("general"));
testString *s = new testString("additional");
attrMapNames.push_back(s);
}
};

int main(int argc, char *argv[])
{
DocObject *dObj = new DocObject;

delete dObj;

return EXIT_SUCCESS;
}

___________
Программа выводит след.:
testString constructor called
testString constructor called
testString destructor called
testString destructor called
___________
Как видим, на два конструктора = два деструктора вызвано. При этом никакого явного вызова деструкторов не требуется.

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

 
Форум » Разработка ПО и игр » С++, STL, Boost и все все все » STL и Boost: сравнение контейнеров list, vector, ...
Страница 1 из 11
Поиск:

Михаил, 2017      Создать бесплатный сайт с uCoz