Maison > Article > développement back-end > Explorez les pointeurs intelligents en C++
Les pointeurs intelligents sont un concept très important en C++. Son rôle est d'aider les programmeurs à prévenir les fuites de mémoire et en même temps de fournir une méthode de gestion de la mémoire plus pratique et flexible. Cet article procédera à une exploration détaillée des concepts, des types et de l'utilisation des pointeurs intelligents.
Les pointeurs intelligents sont une technologie moderne de gestion de la mémoire C++ qui stocke des pointeurs qui encapsulent l'allocation et la libération de mémoire dans des objets pointeurs intelligents. Étant donné que le langage C++ ne gère pas automatiquement la mémoire des programmeurs et que ceux-ci oublient souvent de libérer de la mémoire, l'utilisation de pointeurs intelligents peut réduire considérablement la possibilité de ces problèmes.
Un autre avantage des pointeurs intelligents est qu'ils peuvent améliorer la maintenabilité des programmes, car ils déplacent la libération de mémoire et la gestion du cycle de vie des objets du programmeur vers la bibliothèque de pointeurs intelligents. Dans le C++ moderne, le code qui utilise des pointeurs intelligents a tendance à être plus robuste et moins sujet aux erreurs que le code qui utilise des pointeurs bruts.
Il existe trois types de pointeurs intelligents en C++ : unique_ptr, shared_ptr et faible_ptr. Ils sont tous définis dans le fichier d'en-tête standard
(1) unique_ptr
unique_ptr est un pointeur exclusif, qui garantit qu'un seul pointeur intelligent peut pointer vers un objet à tout moment. En d’autres termes, unique_ptr interdit plusieurs pointeurs pointant vers le même objet. Si vous souhaitez transférer un pointeur unique_ptr vers un autre pointeur intelligent, vous devez utiliser la fonction std::move().
Ce qui suit est un exemple de code pour démontrer l'utilisation de base de unique_ptr :
std::unique_ptr<int> up(new int(10)); // 声明unique_ptr指针,并分配一个int类型的动态内存区域 std::cout << *up << std::endl; // 输出10 *up = 20; // 修改动态内存中的值 std::cout << *up << std::endl; // 输出20
Il convient de noter que lorsque le pointeur unique_ptr quitte sa portée, la mémoire dynamique vers laquelle il pointe sera automatiquement libérée. (Même s'il y a une exception levée)
(2) shared_ptr
shared_ptr peut partager le même objet avec plusieurs pointeurs, et vous pouvez utiliser la fonction use_count() pour obtenir le nombre de pointeurs pointant vers le même objet. Étant donné que plusieurs pointeurs peuvent pointer vers le même objet, il faut veiller à éviter les situations de référence circulaire, qui peuvent entraîner des fuites de mémoire.
L'utilisation de l'exemple de code est la suivante :
std::shared_ptr<int> sp1(new int(10)); std::shared_ptr<int> sp2 = sp1; std::cout << *sp1 << std::endl; // 输出10 std::cout << *sp2 << std::endl; // 输出10 std::cout << sp1.use_count() << std::endl; // 输出2
Il convient de noter que chaque fois qu'un nouveau pointeur shared_ptr pointe vers la même zone mémoire, le nombre de références dans la zone mémoire augmentera de 1. De même, lorsqu'un pointeur quitte sa portée, le nombre de références est décrémenté en conséquence. La mémoire ne sera libérée que lorsque le compteur de référence atteint 0. (Même s'il y a une exception levée)
(3) faible_ptr
weak_ptr est une version plus légère de shared_ptr. Il ne peut pas contrôler l'objet pointé et doit être converti en shared_ptr avant utilisation. Comme cela n’affecte pas le comptage de références, cela ne provoque pas de fuites de mémoire. Cependant, il convient de noter que lors de l'utilisation de faible_ptr, vous devez vous assurer que l'objet pointé existe, sinon l'utilisation de l'interface qu'il fournit entraînera une erreur de programme.
Voici un exemple d'utilisation de faible_ptr :
std::shared_ptr<int> sp1(new int(10)); std::weak_ptr<int> wp = sp1; std::cout << *wp.lock() << std::endl; // 使用weak_ptr提供的lock()函数将其转化为shared_ptr,并访问内存中的值 std::cout << wp.use_count() << std::endl; // 输出1
Il est à noter que lorsque l'objet pointé est supprimé, le shared_ptr renvoyé par faible_ptr.lock() sera vide.
L'utilisation de pointeurs intelligents peut grandement simplifier la tâche de gestion de la mémoire car ils peuvent libérer automatiquement la mémoire dynamique qu'ils gèrent. Lors de l'utilisation d'un pointeur intelligent, il doit être initialisé avec une valeur de retour d'allocation de mémoire dynamique. Vous trouverez ci-dessous un exemple de code pour aider les lecteurs à mieux comprendre l'utilisation des pointeurs intelligents.
// 使用unique_ptr std::unique_ptr<int> up(new int(10)); std::unique_ptr<float[]> u_arr( new float[5] ); // 对数组使用unique_ptr // 使用shared_ptr std::shared_ptr<int> sp(new int(10)); std::shared_ptr<double> sp_arr(new double[5], [](double* p){ delete[] p; }); // 对数组使用shared_ptr,并在内部传递匿名的lambda表达式释放动态内存 std::shared_ptr<Base> spb = std::make_shared<Base>(); // 使用std::make_shared创建shared_ptr指针 std::shared_ptr<Derived> spd = std::make_shared<Derived>(); // 使用weak_ptr std::weak_ptr<int> wp; if (auto sp = wp.lock()) // 使用wp.lock()检查指向的对象 { // 操作所指向的对象 } else { // 找不到所指向的对象 }
Il convient de noter que si un pointeur ordinaire et un pointeur intelligent sont utilisés pour pointer vers la même mémoire dynamique, le pointeur intelligent sera détruit avant le pointeur ordinaire, ce qui peut facilement amener le pointeur ordinaire à pointer vers une mémoire libérée ( inutilisable) espace mémoire.
Les pointeurs intelligents sont une méthode de gestion de la mémoire C++ très utile. Ils peuvent empêcher les fuites de mémoire dans une certaine mesure et également améliorer la maintenabilité du programme. Dans les normes postérieures à C++11, les pointeurs intelligents sont recommandés comme méthode privilégiée de gestion de la mémoire. Dans le processus de développement actuel, vous devez choisir le type de pointeur intelligent à utiliser en fonction de la situation spécifique pour obtenir le meilleur effet de gestion de la mémoire.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!