shared_ptr p(q)Указатель p управляет объектом, на который указывает указатель встроенного типа q; указатель q должен указывать на область памяти, зарезервированную оператором new, а его тип должен быть преобразуем в тип Т*
shared_ptr p(u)Указатель p учитывает собственность указателя u типа unique_ptr; указатель u становится нулевым
shared_ptr p(q, d)Указатель p учитывает собственность объекта, на который указывает встроенный указатель q. Тип указателя q должен быть преобразуем в тип Т* (см. раздел 4.11.2). Для освобождения q указатель p будет использовать вызываемый объект d (см. раздел 10.3.2) вместо оператора delete
shared_ptr p(p2, d)Указатель p — это копия указателя p2 типа shared_ptr, как описано в табл. 12.2, за исключением того, что указатель p использует вызываемый объект d вместо оператора delete
p.reset() p.reset(q) p.reset(q, d)Если p единственный указатель shared_ptr на объект, функция reset() освободит существующий объект p. Если передан необязательный встроенный указатель q, то p будет указывать на q, в противном случае p станет нулевым. Если предоставлен вызываемый объект d, то он будет вызван для освобождения указателя q, в противном случае используется оператор delete

Инициализация указателя p1 неявно требует, чтобы компилятор создал указатель типа shared_ptr из указателя int*, возвращенного оператором new. Поскольку нельзя неявно преобразовать обычный указатель в интеллектуальный, такая инициализация ошибочна. По той же причине функция, возвращающая указатель shared_ptr, не может неявно преобразовать простой указатель в своем операторе return:

shared_ptr clone(int p) {

 return new int(p); // ошибка: неявное преобразование

                    // в shared_ptr

}

Следует явно связать указатель shared_ptr с указателем, который предстоит возвратить:

shared_ptr clone (int p) {

 // ok: явное создание shared_ptr из int*

 return shared_ptr(new int(p));

}

По умолчанию указатель, используемый для инициализации интеллектуального указателя, должен указывать на область динамической памяти, поскольку по умолчанию интеллектуальные указатели используют оператор delete для освобождения связанного с ним объекта. Интеллектуальные указатели можно связать с указателями на другие виды ресурсов. Но для этого необходимо предоставить собственную функцию, используемую вместо оператора delete. Предоставление собственного кода удаления рассматривается в разделе 12.1.4.

Не смешивайте обычные указатели с интеллектуальными

Указатель shared_ptr может координировать удаление только с другими указателями shared_ptr, которые являются его копиями. Действительно, этот факт — одна из причин, по которой рекомендуется использовать функцию make_shared(), а не оператор new. Это связывает указатель shared_ptr с объектом одновременно с его резервированием. При этом нет никакого способа по неосторожности связать ту же область памяти с несколькими независимо созданными указателями shared_ptr.

Рассмотрим следующую функцию, работающую с указателем shared_ptr:

// ptr создается и инициализируется при вызове process()

void process(shared_ptr ptr) {

 // использование ptr

} // ptr выходит из области видимости и удаляется

Перейти на страницу:

Похожие книги