2015-12-03 12 views
10

Non riesco proprio a capire come std::enable_shared_from_this::shared_from_this restituisca un pinter condiviso che condivide la proprietà con il puntatore esistente. In altre parole si fa this:Come std :: enable_shared_from_this :: shared_from_this works

std::shared_ptr<Foo> getFoo() { return shared_from_this(); } 

Così, quando si chiama getFoo come fa esattamente quello che ottiene è l'altro shared_ptr per condividere la proprietà con e non per creare un separato shared_ptr che possiede lo stesso this.

Ho bisogno di capire questo per essere in grado di capire come creare shared_ptr da alcuni oggetti che aumentano tutti lo stesso conteggio ref e non inizializzare separati shared_ptr s.

+2

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this Date un'occhiata alle note – StoryTeller

+0

ho visto le note che descrivono l'applicazione comune . Prima di allora, ho anche guardato il codice sorgente. Ma non ho capito come questo 'weak_ptr' viene inizializzato quando first_ptr è bing creato al di fuori della classe. Una classe non può sapere che abbiamo incapsulato il suo puntatore in alcuni 'shared_ptr'. – Narek

+2

Si dovrebbe anche dare un'occhiata al sorgente di 'std :: shared_ptr'. La nota specifica chiaramente che esiste un codice che rileva la presenza di 'std :: enable_shared_from_this' come una classe base. – StoryTeller

risposta

16

enable_shared_from_this<T> ha un membro dati weak_ptr<T>. Il costruttore shared_ptr<T> è in grado di rilevare se è derivato da enable_shared_from_this<T>. In caso affermativo, il costruttore shared_ptr<T> assegnerà *this (che è il shared_ptr<T>) al membro dei dati weak_ptr in enable_shared_from_this<T>. shared_from_this() può quindi creare un shared_ptr<T> dal weak_ptr<T>.

Esempio di una possibile implementazione:

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; 
    } 
} 
+0

Come 'shared_ptr' ha accesso al membro' weak_ptr' (immagino sia privato) di 'enable_shared_from_this'. – Narek

+3

@Narek probabilmente è un 'amico'. – Simple

+0

In C++ 17, è possibile compilare il controllo 'if' (che è attualmente * pseudo-codice *) compilabile usando il ramo compilato come:' if constexpr (...) {...} ' – Nawaz

Problemi correlati