Ultimamente ho imparato i puntatori gestiti e mi sono imbattuto nel seguente scenario.C++ shared_ptr di stack object
Sto implementando una classe model/controller per una vista di gioco. La mia opinione, renderà le cose nel modello. Abbastanza diretto. Nella mia funzione principale, ho un'istanza di tutti e tre in questo modo:
RenderModel m;
m.AddItem(rect); // rect gets added just fine, it's an "entity" derivee
RenderView v;
v.SetModel(m);
il mio render vista della classe è abbastanza semplice:
class RenderView
{
public:
explicit RenderView();
~RenderView();
void Update();
void SetModel(RenderModel& model);
private:
// disable
RenderView(const RenderView& other);
RenderView& operator=(const RenderView& other);
// private members
boost::scoped_ptr<RenderModel> _model;
};
L'implementazione per setview è abbastanza standard:
void RenderView::SetModel(RenderModel& model)
{
_model.reset(&model);
}
Il la chiave per questo è, la vista memorizza un modello in un puntatore intelligente. Tuttavia, in main, il modello è stato assegnato in pila. Quando il programma termina, la memoria viene eliminata due volte. Questo ha senso. La mia attuale comprensione mi dice che tutto ciò che viene memorizzato in uno smart_ptr (di qualsiasi tipo) non dovrebbe essere stato allocato nello stack.
Dopo tutte le impostazioni di cui sopra, la mia domanda è semplice: come faccio a dettare che un parametro non è stato allocato nello stack? Accettare un puntatore intelligente come parametro è l'unica soluzione? Anche allora non potevo garantire che chiunque usi la mia classe di visualizzazione non poteva fare qualcosa di sbagliato, come:
// If I implemented SetModel this way:
void RenderView::SetModel(const std::shared_ptr<RenderModel>& model)
{
_model.reset(&*model);
}
RenderModel m;
RenderView v;
std::shared_ptr<RenderModel> ptr(&m); // create a shared_ptr from a stack-object.
v.SetModel(ptr);
Se il chiamante non interpreta correttamente shared_ptr, presumo che non ci sia modo di rilevare qualcosa di simile? Chiedo semplicemente, perché sento che potrei fare di nuovo questo errore, e non voglio passare ore a ri-debugare il problema. Potrei lasciarmi una nota appiccicosa sul mio monitor fino a quando non mi brucia nella testa ... – Short
Ci sono alcuni "trucchi" noti per rilevare se un oggetto vive nello stack o nell'heap, come confrontare gli indirizzi. Tutti questi relè si basano su un comportamento non definito o dipendente dall'implementazione. Suppongo che se è giusto accennare a te stesso potrebbe funzionare, ma non sono una soluzione reale. –
No, se la tua funzione accetta 'std :: shared_ptr', non c'è modo di dire se quel puntatore punta a un oggetto valido. Detto questo, se prende esplicitamente un 'std :: shared_ptr', è molto più difficile sbagliare (il codice che costruisce un' std :: shared_ptr' da una variabile locale sembra a prima vista sbagliato ed è facile da evitare). –