23 General utilities library [utilities]

23.11 Smart pointers [smartptr]

23.11.2 Shared-ownership pointers [util.smartptr]

23.11.2.3 Class template weak_­ptr [util.smartptr.weak]

В weak_­ptr шаблоне класса хранится слабая ссылка на объект, которым уже управляет shared_­ptr. Для доступа к объекту a weak_­ptr можно преобразовать в a shared_­ptr с помощью функции-члена lock.

namespace std {
  template<class T> class weak_ptr {
  public:
    using element_type = T;

    // [util.smartptr.weak.const], constructors
    constexpr weak_ptr() noexcept;
    template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
    weak_ptr(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
    weak_ptr(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;

    // [util.smartptr.weak.dest], destructor
    ~weak_ptr();

    // [util.smartptr.weak.assign], assignment
    weak_ptr& operator=(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
    template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    weak_ptr& operator=(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;

    // [util.smartptr.weak.mod], modifiers
    void swap(weak_ptr& r) noexcept;
    void reset() noexcept;

    // [util.smartptr.weak.obs], observers
    long use_count() const noexcept;
    bool expired() const noexcept;
    shared_ptr<T> lock() const noexcept;
    template<class U> bool owner_before(const shared_ptr<U>& b) const;
    template<class U> bool owner_before(const weak_ptr<U>& b) const;
  };

  template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;


  // [util.smartptr.weak.spec], specialized algorithms
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
}

Специализации weak_­ptr должны быть CopyConstructible и CopyAssignable, позволяющие использовать их в стандартных контейнерах. Параметр шаблона T из weak_­ptr может быть неполным типом.

23.11.2.3.1 weak_­ptr constructors [util.smartptr.weak.const]

constexpr weak_ptr() noexcept;

Effects: Создает пустой weak_­ptr объект.

Postconditions: use_­count() == 0.

weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;

Remarks: Второй и третий конструкторы не должны участвовать в разрешении перегрузки, если они Y* не совместимы с T*.

Effects: Если r пусто, создает пустой weak_­ptr объект; в противном случае создает weak_­ptr объект, который разделяет владение r и хранит копию указателя, хранящегося в r.

Postconditions: use_­count() == r.use_­count().

weak_ptr(weak_ptr&& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;

Remarks: Второй конструктор не должен участвовать в разрешении перегрузки, если он Y* не совместим с T*.

Effects: Move создает weak_­ptr экземпляр из r.

Postconditions: *this должен содержать старое значение r. r будет пустым. r.use_­count() == 0.

23.11.2.3.2 weak_­ptr destructor [util.smartptr.weak.dest]

~weak_ptr();

Effects: Уничтожает этот weak_­ptr объект, но не влияет на объект, на который указывает его сохраненный указатель.

23.11.2.3.3 weak_­ptr assignment [util.smartptr.weak.assign]

weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;

Effects: Эквивалентно weak_­ptr(r).swap(*this).

Remarks: Реализация может обеспечить эффекты (и подразумеваемые гарантии) разными способами, не создавая временного.

Returns: *this.

weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;

Effects: Эквивалентно weak_­ptr(std​::​move(r)).swap(*this).

Returns: *this.

23.11.2.3.4 weak_­ptr modifiers [util.smartptr.weak.mod]

void swap(weak_ptr& r) noexcept;

Effects: Меняет содержимое *this и r.

void reset() noexcept;

Effects: Эквивалентно weak_­ptr().swap(*this).

23.11.2.3.5 weak_­ptr observers [util.smartptr.weak.obs]

long use_count() const noexcept;

Returns: 0 если *this пусто; в противном случае - количество shared_­ptr экземпляров, с которыми совместно владеют *this.

bool expired() const noexcept;

Returns: use_­count() == 0.

shared_ptr<T> lock() const noexcept;

Returns: expired() ? shared_­ptr<T>() : shared_­ptr<T>(*this), выполняется атомарно.

template<class U> bool owner_before(const shared_ptr<U>& b) const; template<class U> bool owner_before(const weak_ptr<U>& b) const;

Returns: Неуказанное значение такое, что

  • x.owner_­before(y) определяет строгий слабый порядок, как определено в [alg.sorting];

  • по отношению эквивалентности , определенное owner_­before, !a.owner_­before(b) && !b.owner_­before(a)два shared_­ptr или weak_­ptr экземпляры эквивалентны тогда и только тогда , когда они имеют право собственности или являются пустыми.

23.11.2.3.6 weak_­ptr specialized algorithms [util.smartptr.weak.spec]

template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

Effects: Эквивалентно a.swap(b).