2010-10-07 11 views
6

J'ai une application C++ qui utilise largement des pointeurs pour maintenir des structures de données assez complexes. L'application effectue des simulations mathématiques sur d'énormes ensembles de données (ce qui pourrait prendre plusieurs Go de mémoire), et est compilé avec Microsoft Visual Studio 2010.Mise en route avec des pointeurs intelligents en C++

Je suis en train de retravailler une partie importante de l'application. Pour réduire les erreurs (pointeurs pendants, fuites de mémoire, ...) je voudrais commencer à utiliser des pointeurs intelligents. Sacrifier la mémoire ou la performance est acceptable tant qu'il est limité.

En pratique, la plupart des classes sont maintenues dans de grands pools (un pool par classe) et bien que les classes puissent se référer les unes aux autres, vous pouvez considérer le pool comme propriétaire de toutes les instances de cette classe. Cependant, si le pool décide de supprimer une instance, je ne souhaite pas que les autres classes qui font encore référence à l'instance supprimée aient un pointeur suspendu.

Dans une autre partie, je conserve une collection de pointeurs vers des instances qui sont fournies par d'autres modules dans l'application. En pratique, les autres modules conservent la propriété de l'instance transmise, mais dans certains cas, les modules ne veulent pas prendre en charge la propriété et veulent juste passer l'instance à la collection, en lui disant "c'est à vous de la gérer maintenant". Quel est le meilleur moyen de commencer à introduire des pointeurs intelligents?

Le simple remplacement des pointeurs [au hasard] par des pointeurs intelligents ne semble pas être une bonne façon de procéder, et ne fournit probablement pas tous les avantages (ou l'un des) des pointeurs intelligents. Mais quelle est la meilleure méthode?

Quels types de pointeurs intelligents devrais-je étudier plus en détail? J'utilise parfois std :: auto_ptr pour la désallocation de la mémoire allouée localement, mais cela semble être déprécié en C++ 0x. Std :: unique_ptr est-il une meilleure alternative? Ou devrais-je aller directement aux pointeurs partagés ou à d'autres types de pointeurs intelligents? La question Replacing existing raw pointers with smart pointers semble similaire mais au lieu de demander comment c'est facile, je demande quelle serait la meilleure approche, et quel type de pointeurs intelligents sont les mieux adaptés.

Merci d'avance pour vos idées et suggestions.

Répondre

1

Voici les 3 variétés trouvées dans la nouvelle norme C++ 11 (unique_ptr remplace auto_ptr)

http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr

http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr

http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr

Vous pouvez lire le texte pour chaque pointeur et il y a une explication de quand utiliser quoi dedans. Pour la gestion de la mémoire locale, unique_ptr est le choix. Il est non-copiable mais mobile de sorte que lorsque vous le déplacez autour du récepteur prend possession de celui-ci. Shared_ptr est utilisé si vous voulez partager une instance d'objet sans que personne ne possède réellement l'objet et pour vous assurer qu'il n'est pas supprimé tant que quelqu'un y fait référence. Une fois que le dernier utilisateur d'un objet a détruit le conteneur shared_ptr, l'objet contenu sera supprimé. Weak_ptr est utilisé en conjonction avec shared_ptr. Il permet de "verrouiller" pour voir si l'objet de référence shared_ptr existe toujours avant d'essayer d'accéder à l'objet interne.

3

Je recommande d'utiliser unique_ptr si possible (cela peut nécessiter une analyse de programme) et shared_ptr lorsque cela est impossible. En cas de doute, utilisez un shared_ptr pour maximiser la sécurité: lors du transfert du contrôle à un conteneur, le compteur de référence passera simplement à deux puis à un seul et le conteneur finira par delete automatiquement l'objet associé. Lorsque la performance devient un problème, pensez à utiliser boost::intrusive_ptr.

+0

+1 bon conseil. Vous devez faire un * lot * de création/destruction d'objet ou de copie de pointeur pour voir une différence de performance entre 'shared_ptr' et' intrusive_ptr'. – Doug