2010-10-11 14 views
3

Le code suivant signifie-t-il que lorsque cette fonction est renvoyée, l'objet de requête dans cette classe contient toujours une référence à cet objet?Nombre de références lors du renvoi d'un shared_ptr

boost::shared_ptr<Request> RequestList::GetRequest() 
{ 
    boost::mutex::scoped_lock(listmtx); 
    request = boost::shared_ptr<Request>(new Request()); 
    return request; 
} 

utilisé:

request = requests->GetRequest(); //Ref count is two on request object when it returns?? 

même après avoir terminé au-dessus de la cession, nous avons encore un compte de référence de deux sur request ...

où les demandes est juste un pointeur RequestList (pointeur brut) ...

+1

Où est 'request' déclarée? Est-ce censé être local dans 'GetRequest' ou existe-t-il ailleurs? Cela fait beaucoup de différence ... – Potatoswatter

+0

demande est une variable de classe privée ... –

Répondre

1

Il est deux sur le retour, un à la fin de la déclaration.

request = boost::shared_ptr<Request>(new Request()); // ref count = 1 
return request; // makes a copy of request. ref count = 2 

Alors quand il revient c'est 2 parce qu'il y a un temporaire.

request = requests->GetRequest(); // it's two because there is still a temporary 
// at the end of the statement all the temporaries are destroyed, 
// ref count decremented to 1 

Bien sûr, vous pouvez utiliser request.use_count() pour obtenir le nombre de référence.

+0

C'était ma pensée initiale, mais le temporaire est détruit * avant * la fonction renvoie (à la fin de l'expression complète de l'instruction de retour). Quoi qu'il en soit, à moins qu'il ne compile avec '-O0', l'élision de copie empêche cela de se produire. – Potatoswatter

+0

@Potatoswatter: Quel temporaire ??? Nous parlons du temporaire à l'énoncé d'assignation en dehors de GetRequest. – ybungalobill

+0

le compte ref ne va pas à un après avoir terminé l'instruction d'affectation ... –

2

Le nombre de références est égal au nombre de pointeurs partagés existants. Dans ce cas, après avoir créé le pointeur partagé, vous obtenez deux copies (l'affectation à request à l'intérieur de GetRequest(), que je suppose être un membre de RequestList, et l'affectation à request du résultat de GetRequest()) .

Si les deux sont des pointeurs partagés, et ils ne font pas tous deux référence au même pointeur, alors vous obtiendrez deux copies du pointeur d'origine, et donc un nombre de référence de deux.

+0

Dois-je les faire se référer au même pointeur ?? Désolé d'avoir l'air idiot, mais toute cette idée de compte de référence n'est pas tout à fait clair pour moi ... –

+1

Je suis sûr que vous ne voulez pas qu'ils se réfèrent au même pointeur; J'affirmais simplement mon hypothèse qu'ils ne le font pas. Fondamentalement, tout ce qui a besoin de la requête pour exister devrait avoir un pointeur partagé, et il existera aussi longtemps que n'importe lequel des pointeurs. Dans votre code, la liste conserve un pointeur partagé, en plus d'en donner un à tout ce qu'on appelle 'GetRequest', donc la propriété est partagée entre les deux objets. Si vous voulez simplement que la liste distribue une requête et ne se soucie pas de la supprimer, ne conservez pas un pointeur partagé dans la liste. –

4

demande est une variable de classe privée ...

Ensuite, il y a deux shared_ptr objets avec une poignée à l'new Request(): celui de la fonction d'appel et la variable de classe privée. Les deux bousculent légitimement le refcount.

À moins qu'il existe une raison pour que la variable de classe privée existe, éliminez-la. À tout le moins, renommez-le last_request, parce que c'est ce que c'est vraiment.

(Bien sûr, quand last_request obtient muter un autre appel à GetRequest, sa poignée à la demande précédente disparaît.)