la sicurezza di passare boost :: riferimento shared_ptr
-
15-10-2019 - |
Domanda
la mia domanda è: come fail-safe è il seguente frammento di codice che fa parte del mio gestore di risorse:
bool Load(std::string name, boost::shared_ptr<Asset::Model>& newModel)
{
std::map<std::string, boost::scoped_ptr<Asset::Model> >::const_iterator seeker;
seeker = models.find(name);
if (seeker == models.end())
return false;
newModel = seeker->second->Copy(); // Copy returns a boost::shared_ptr<Asset::Model>
return true;
}
private:
std::map< std::string, boost::scoped_ptr<Asset::Model> > models;
perché passando shared_ptr di spinta con riferimento non è in realtà parte del concetto shared_ptr, se io uso solo in questo ambito, potrei avere dei problemi?
Soluzione
Questo utilizzo è sicuro, in quanto qualunque shared_ptr<>
passata attraverso il riferimento avrà essa la refcount ridotto (assumendo che il shared_ptr<>
tornati da seeker->second->Copy()
non è un shared_ptr<>
allo stesso oggetto) e pertanto l'oggetto verrà puntato potrebbe essere cancellato.
In particolare, non si crea una seconda shared_ptr<>
da un puntatore grezzo (che è un errore perché creerebbe un secondo, shared_ptr<>
non collegati con un refcount separata, e quindi un secondo proprietario dell'oggetto).
Sia che la vostra funzione fornisce il comportamento desiderato dipende da ciò che si desidera.
Altri suggerimenti
I guess you want to do something like this:
boost::shared_ptr<Asset::Model> ptr;
if(Load("stuff", ptr))
{
doSomething with ptr
}
In this case you should be fine.
However you don't need to use a reference here. Just return a shared_ptr
and set it to 0 if no element was found:
boost::shared_ptr<Asset::Model> Load(std::string name)
{
std::map<std::string, boost::scoped_ptr<Asset::Model> >::const_iterator seeker;
boost::shared_ptr<Asset::Model> retPtr;
seeker = models.find(name);
if (seeker == models.end())
return retPtr;
retPtr = seeker->second->Copy(); // Copy returns a boost::shared_ptr<Asset::Model>
return retPtr;
}
However I noticed you are using scoped_ptr
in a standard container - which AFAIK is not possible.