2014-12-10 7 views
6

Se voglio creare un shared_ptr<Derived> in una funzione membro della classe derivata in una gerarchia che eredita da una classe base, posso usare shared_from_this e static_pointer_cast:Come posso usare shared_from_this in una classe derivata senza manipolazioni RC superflue?

class Base: public std::enable_shared_from_this<Base> { 
}; 

class Der: public Base { 
public: 
    std::shared_ptr<Der> make_SP_to_Me() 
    { return std::static_pointer_cast<Der>(shared_from_this()); } 
}; 

mia preoccupazione è che static_pointer_cast accetta la sua argomentazione lvalue- ref-to-const, quindi quando viene creato il nuovo shared_ptr<Der>, il conteggio dei riferimenti nel blocco di controllo viene incrementato. Quando il numero shared_ptr<Base> viene restituito da shared_from_this viene eliminato, il valore del contatore nel blocco di controllo verrà nuovamente diminuito. Sono rimasto sorpreso nel constatare che non esiste un sovraccarico dello static_pointer_cast che preveda la necessità di manipolare il contatore nel blocco di controllo.

shared_ptr<T> ha un costruttore templatizzato che assume valori di tipo shared_ptr<U> che eseguono spostamenti, evitando così la necessità di eseguire manipolazioni del conto. C'è qualche ragione per cui lo static_pointer_cast non fa la stessa cosa? E c'è un modo per me di scrivere il codice sopra che non comporta manipolazioni inutili del conto?

+2

Sì, tutti quei cast di puntatori dovrebbero usare riferimenti universali ... http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast Una seria supervisione da parte del comitato. – Deduplicator

+0

@Deduplicator: BTW il nuovo termine sarà probabilmente "forwarding reference" (vedi alcuni video di CppCon 2014 di Herb Sutter) –

risposta

1

Sembra che dovrai fare affidamento sull'ottimizzazione del valore di ritorno e sperare che sia abbastanza intelligente da aiutarti.

Se std::*_pointer_cast aveva sovraccarichi che accettano i riferimenti di inoltro (T&&), allora potevano trasferire la proprietà dai provvisori e questo non sarebbe un problema. Lo considero una svista nella libreria dal C++ 11.

Problemi correlati