17 Temmuz 2019 Çarşamba

std::enable_shared_from_this

Giriş
Şu satırı dahil ederiz.
#include <memory>
Bir nesne kendine shared_ptr dönmek isterse kullanılır. std::enable_shared_from_this "Curiously recurring template pattern" yani CRTP tasarım örüntüsünü kullanır.

Örnek
std::enabled_shared_from_this kalıtımın public olması gerekir. Şu kod yanlış.
class MyClass : std::enable_shared_from_this<MyClass>
{
  ...
};
Örnek
Şöyle yaparız.
class Y: public enable_shared_from_this<Y>
{
public:

  shared_ptr<Y> f()
  {
    return shared_from_this();
  }
}

int main()
{
  shared_ptr<Y> p(new Y);
  shared_ptr<Y> q = p->f();
  assert(p == q);
  assert(!(p < q || q < p)); // p and q must share ownership
}
Örnek
Çağrı zinciri yapmak için kullanılabilir.Tüm setter metodları kendisini dönen bir sınıfımız olsun.
class Foo : public enable_shared_from_this<Foo> {
public:
  typedef shared_ptr<Foo> Ptr;

  Ptr setA(int) {/* .... */ return this->shared_from_this(); } 
  Ptr setB(int) {/* .... */ return this->shared_from_this(); } 
  Ptr setC(int) {/* .... */ return this->shared_from_this(); } 
};
Bu sınıfı şöyle kullanabiliriz.
Foo::Ptr foo = make_shared<Foo>();
foo->setA(3)->setB(4)->setC(5);
İçin Nasıldır
std::enable_shared_from_this kendi içinde bir weak_ptr tanımlar. İçi şuna benzer.
template<class D>
class enable_shared_from_this {
protected:
  constexpr enable_shared_from_this() { }
  enable_shared_from_this(enable_shared_from_this const&) { }
  enable_shared_from_this& operator=(enable_shared_from_this const&) {
    return *this;
  }

public:
  shared_ptr<T> shared_from_this() { return self_.lock(); }
  shared_ptr<T const> shared_from_this() const { return self_.lock(); }

private:
  weak_ptr<D> self_;

  friend shared_ptr<D>;
};

template<typename T>
shared_ptr<T>::shared_ptr(T* ptr) {
  // ...
  // Code that creates control block goes here.
  // ...

  // NOTE: This if check is pseudo-code. Won't compile. There's a few
  // issues not being taken in to account that would make this example
  // rather noisy.
  if (is_base_of<enable_shared_from_this<T>, T>::value) {
    enable_shared_from_this<T>& base = *ptr;
    base.self_ = *this;
  }
}





Hiç yorum yok:

Yorum Gönder