7. Указатели std_shared_ptr, std_weak_ptr, особенности использования make_shared (1186013)
Текст из файла
Проектирование больших систем наC++Коноводов В. А.кафедра математической кибернетики ВМКЛекция 720.10.2017std::shared_ptrIРеализует семантику совместного владения.IИспользует метод подсчета ссылок. Счетчик ссылокхранится в динамически выделяемой памяти. Объект просчетчик ссылок ничего не знает.IТип удалителя не является частью типа указателя.IМожет работать только для указателей на объекты.Что происходит здесь?sp1 = sp2;Некоторые методы std::shared_ptrIuse_count — количество shared ptr’ов, ссылающихся наэтот же объект;Ireset — заменяет объект;Iunique — проверяет, что объект контролируетсяединственным указателем shared ptr;Iget — возвращает указатель на объект, которым владеет;std::shared_ptrIПеремещение быстрее копирования.IСчетчик ссылок хранится в динамически выделяемойпамяти.IПользовательский удалитель не является частью типауказателя.Управляющий блокIФункция std::make_shared всегда создает управляющийблок.IУправляющий блок создается, когда указательstd::shared_ptr создается из указателя сисключительным владениемIКогда конструктор.
std::shared_ptr вызывается собычным указателем — он создает управляющий блок.Типичная ошибкаA* p = new A;std::shared_ptr<A> sptr1(p);std::shared_ptr<A> sptr2(p);std::weak_ptrДополнение функциональности std::shared_ptr.Iне участвует в совместном владении,Iпозволяет понять, не является ли указатель висячим,Iнельзя ни разыменовать, ни проверить на nullptr.auto sp = std::make_shared<A>();std::weak_ptr<A> wp(sp);// sp.use_count() == 1, wp.expired() == false;// нельзя написать *wp, можно написать *spsp = nullptr;// sp.use_count() == 0, wp.expired() == true;std::weak_ptrРазыменование происходит через преобразование кstd::shared_ptr<>:IЧерез функцию lock() – удаленный объект соответствуетnullptr.IПрямая конвертация – удаленный объект вызываетисключение.auto sp2 = wp.lock();// sp2 нулевой, если wp expiredstd::shared_ptr<A> sp3(wp);// exception std::bad_weak_ptr, если wp expiredstd::weak_ptr: зачем?Пусть есть фабрика объектов:std::unique_ptr<const TObject> BuildObject(int param);Кэш с удалением неиспользованных кэшированных значений.std::shared_ptr<const TObject> FastBuildObject(int param) {static std::unordered_map<int,std::weak_ptr<const TObject>>cache;auto objPtr = cache[param].lock();if (!objPtr) {objPtr = BuildObject(param);cache[param] = objPtr;}return objPtr;}Предупреждение циклов std::shared_ptrРассмотрим такую структуру совместного владения:Aeshared_ptr B/??Каким должен быть указатель?Iraw pointerIshared_ptrIweak_ptroshared_ptr CСчетчик слабых ссылокВремя между уничтожением последнего shared_ptr и weak_ptrзначительно.auto sp = std::make_shared<A>();// создание shared_ptr, weak_ptr// ..// удаление всех shared_ptr// ...
(!)// удаление последнего weak_ptrИли через new?std::make_sharedГде тут потенциальная проблема?Do(std::shared_ptr<A>(new A), getItem());Исправляем:Do(std::make_shared<A>(), getItem());+ единовременное выделение памяти под объект и счетчик ссылокНо в std::make_shared нельзя использовать custom-удалитель:std::shared_ptr<A> sp(new A, customDeleter);Как тогда исправитьDo(std::shared_ptr<A>(new A, customDeleter), getItem());чтобы было безопасно?std::shared_ptr<A> sp(new A, customDeleter);Do(sp, getItem());Чего не хватает теперь для оптимальности?std::make_sharedПрименение make-функций может быть плохой идеей дляобъектов типов с перегруженными operator new и operatordelete.Тут может помочьstd::allocate_shared<>и собственный аллокатор.Другие умные указателиIintrusive_ptr — облегченная версия shared_ptr дляклассов, имеющих встроенные механизмы подсчётассылок.Iscoped_ptr — аналог const auto_ptr с запрещеннымиконструктором копирования и оператором присваивания..
Характеристики
Тип файла PDF
PDF-формат наиболее широко используется для просмотра любого типа файлов на любом устройстве. В него можно сохранить документ, таблицы, презентацию, текст, чертежи, вычисления, графики и всё остальное, что можно показать на экране любого устройства. Именно его лучше всего использовать для печати.
Например, если Вам нужно распечатать чертёж из автокада, Вы сохраните чертёж на флешку, но будет ли автокад в пункте печати? А если будет, то нужная версия с нужными библиотеками? Именно для этого и нужен формат PDF - в нём точно будет показано верно вне зависимости от того, в какой программе создали PDF-файл и есть ли нужная программа для его просмотра.