2015-12-03 4 views
10

Ich kann einfach nicht verstehen, wie std::enable_shared_from_this::shared_from_this einen gemeinsamen Pinter zurückgibt, der den Besitz mit vorhandenem Zeiger teilt. Mit anderen Worten haben Sie this:Wie std :: enable_shared_from_this :: shared_from_this funktioniert

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

Also, wenn Sie getFoo nennen wie funktioniert es genau das, was die anderen shared_ptr ist das Eigentum zu teilen und keine separaten shared_ptr, die besitzt die gleichen this zu erstellen.

Ich muss dies verstehen, um zu verstehen, wie shared_ptr von einem Objekt zu erstellen, die alle die gleiche Ref-Zahl erhöhen und separate shared_ptr s nicht initialisieren.

+2

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this Werfen Sie einen Blick auf die Notizen – StoryTeller

+0

Ich habe die Hinweise gesehen, dass die gemeinsame Umsetzung beschreiben . Davor habe ich mir auch den Quellcode angeschaut. Aber ich konnte nicht verstehen, wie dieses 'weak_ptr' initialisiert wird, wenn zuerst shared_ptr außerhalb der Klasse erstellt wird. Eine Klasse kann nicht wissen, dass wir ihren Zeiger in ein "shared_ptr" eingekapselt haben. – Narek

+2

Sie sollten sich auch die Quelle von 'std :: shared_ptr' ansehen. Die Notiz gibt klar an, dass es Code gibt, der das Vorhandensein von "std :: enable_shared_from_this" als Basisklasse erkennt. – StoryTeller

Antwort

16

enable_shared_from_this<T> hat ein weak_ptr<T> Datenelement. Der shared_ptr<T> Konstruktor kann erkennen, ob T von enable_shared_from_this<T> abgeleitet ist. Wenn dies der Fall ist, weist der shared_ptr<T> Konstruktor *this (shared_ptr<T>) dem Datenelement weak_ptr in enable_shared_from_this<T> zu. shared_from_this() kann dann aus der weak_ptr<T> eine shared_ptr<T> erstellen.

Beispiel einer möglichen Implementierung:

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

Wie 'shared_ptr' Zugriff auf' weak_ptr'-Mitglied (ich denke, es ist privat) von 'enable_shared_from_this'. – Narek

+3

@Narek ist es wahrscheinlich ein 'Freund'. – Simple

+0

In C++ 17 können Sie den 'if'-Check (der derzeit * Pseudo-Code * ist) kompilieren, indem Sie den Kompilierungs-Branch wie folgt verwenden:' if conexpr (...) {...} ' – Nawaz

Verwandte Themen