2010-04-29 7 views
2

Je ne suis pas familier avec les pointeurs intelligents et j'essayais de refactoriser du code existant pour utiliser auto_ptr. La question que je me pose concerne les doubles pointeurs et leur équivalent auto_ptr, si cela a du sens.Pointeur vers auto_ptr au lieu d'un double pointeur classique

J'ai une fonction qui accepte un double pointeur comme paramètre et la fonction alloue des ressources pour elle:

void foo (Image** img) { ... *img = new Image(); ...} 

Cette fonction est alors utilisée comme ceci:

Image* img = NULL; 
foo (&img); 
... 
delete img; 


Je veux utiliser auto_ptr pour éviter d'appeler explicitement delete. Est-ce que ce qui suit est correct?

void foo (auto_ptr<Image>* img) { ... *img = auto_ptr<Image>(new Image()); ...} 

puis

auto_ptr<Image> img = NULL; 
foo (&img); 

Merci.

+1

Si non, pourquoi ne pas retourner un 'auto_ptr'? – UncleBens

+0

Ouais, la fonction renvoie un bool qui indique si tout s'est bien passé. Je suppose que je pourrais juste jeter une exception pour cela ... – Pin

+1

... ou retourner un pointeur 'NULL'? – sbi

Répondre

7

std::auto_ptr<> a étrange sémantique de copie (en fait il est mouvement sémantique, plutôt que de copier la sémantique) et est souvent pas ce que vous voulez quand vous voulez un pointeur intelligent. Par exemple, il ne peut pas être placé dans des conteneurs STL.
Si votre bibliothèque standard est fournie avec le support TR1, utilisez plutôt std::tr1::shared_ptr<>. (Dans le cas contraire, utilisez boost'sboost::shared_ptr<>, qui est ce que std::tr1::shared_ptr<> a été pris de.)

Si vous voulez coller avec std::auto_ptr<> votre code, vous pouvez passer dans la fonction par référence non const:

void foo (std::auto_ptr<Image>& img) { ... img.reset(new Image();) ...} 

std::auto_ptr<Image> img; 
foo (img); 
... 
// no need to delete 

ou vous pouvez simplement retourner le pointeur:

std::auto_ptr<Image> foo() {return std::auto_ptr<Image> img(new Image();)} 
+0

OK, merci. J'ai votre réponse plus vite que je ne pourrais l'éditer, hein. – Pin

0

Cela dépend si oui ou non votre implementaton de STL de auto_ptr remplace le '& 'opérateur pour renvoyer un pointeur vers un pointeur (la plupart des classes de pointeurs intelligentes tendent vers, mais pas toutes les implémentations auto_ptr).

Si vous voulez vraiment ré-écrire votre code pour passer auto_ptr autour des objets, alors vous devriez faire quelque chose de plus comme celui-ci à la place, ce qui serait plus sûr:

void foo (std::auto_ptr<Image> &img) { ... img.reset(new Image()); ...} 

std::auto_ptr<Image> img; 
foo (img); 
+1

Si elle remplace le préfixe unaire '&', elle ne serait pas conforme aux normes. – sbi

0

Puisque vous refactoring, j'irais une étape supplémentaire et convertir le paramètre en une valeur de retour:

// void foo(Image ** img) 
std::auto_ptr<Image> foo() { 
   std::auto_ptr<Image> tmp(new Image()); 
    // ... 
    return tmp; 
} 

Même si je préfère supprimer l'exigence de l'interface (de sorte que l'appelant peut décider de modifier le code à utiliser tout autre type de pointeur intelligent à volonté):

La fonction fait-elle quoi que ce soit avec la valeur transmise elle-même?
Image* foo() { 
    std::auto_ptr<Image> tmp(new Image()); 
    // ... 
    return tmp.release(); 
} 
int main() { 
    std::auto_ptr<Image> ptr(foo()); 
} 
Questions connexes