2016-07-03 36 views
7

È normale ereditare da enable_shared_from_this solo per poter restituire le funzioni membro come l'intenzione primaria, senza intenzione di esporre l'API enable_shared_from_this nella classe derivata. shared_ptr.Il mandato standard enable_shared_from_this deve essere ereditato pubblicamente? Perché?

Dal momento che per utilizzare lo enable_shared_from_this è necessario farlo attraverso l'ereditarietà pubblica (lo standard richiede questo? Qual è la motivazione?), Questo non può essere raggiunto e l'API enable_shared_from_this è forzata in API pubbliche di classe derivata.

Inerendo enable_shared_from_this privatamente e facendo shared_ptr una classe di amici funziona su clang accoppiato con libC++, ma non funziona con stdlibC++.

Dal private enable_shared_from_this + friend shared_ptr (o ereditarietà protetta) sembra coprire questo caso d'uso, non dovrebbe essere sufficiente dallo standard per il montaggio come soluzione per il problema "condiviso da questo"?

+1

Si potrebbe provare ad ereditare 'protected', ad esempio' class T: protected std :: enable_shared_from_this {...}; '? Non l'ho provato da solo –

+0

@ChrisBeck ok grazie. Immagino che la domanda continui a essere valida, se non si desidera fare anche questo ('protected'). –

+0

Penso che non sia possibile che il meccanismo 'shared_from_this' funzioni se l'ereditarietà è totalmente privata. Il modo in cui funziona, se ho capito bene, è che la struttura di controllo per 'shared_ptr' (il conteggio dei riferimenti) è memorizzata in un prefisso nella tua classe, quindi, c'è un membro dei dati in' std :: enable_shared_from_this ' . Per fare un 'shared_ptr' da' this', deve essere in grado di eseguire il cast statico 'this' e trovare il contatore ref. Anche 'std :: make_shared' deve essere in grado di rilevare cose come questa nel tuo tipo. Se l'ereditarietà è privata, suppongo che non possano farlo. Non sono sicuro .. –

risposta

2

Dal private enable_shared_from_this + amico shared_ptr sembra coprire questo caso d'uso, non dovrebbe essere sufficiente dallo standard?

No. Lo standard consente alle implementazioni un'ampia gamma di modalità di implementazione. Il costruttore di shared_ptr<T> che adotta un oggetto può rinviare il materiale condiviso da questo a qualche funzione di supporto o altro oggetto. Per la massima ironia, potrebbe rinviare a una classe base di shared_ptr<T>;)

Come tale, enable_shared_from_this devono essere accessibili da qualsiasi codice in ordine per il costruttore shared_ptr lavorare.

+0

Sembra un compromesso, consentendo implementazioni di latitudine ampia a detrimento dell'API pubblica di ogni utente e vincolandola leggermente per il gusto delle opzioni API dell'utente –

+2

@pepper_chico: Dovrai metterti in fila dietro a tutti coloro che cercano di ottenere puntatori di funzione/puntatori membri alle funzioni di libreria standard. –

+0

Quindi, perché 'enable_shared_from_this ' impone che sia una classe di base pubblica di 'T', cioè,' T * 'è convertibile in' enable_shared_from_this * '? Potrei immaginare un errore in fase di compilazione quando non funziona. – lorro

Problemi correlati