Обмен технологиями

【C】Умный указатель

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Объяснение умных указателей

Smart Pointer — это инструмент на C++, используемый для автоматического управления динамически выделяемой памятью.

Это класс, который инкапсулирует функции необработанных указателей и может автоматически обрабатывать выделение и освобождение ресурсов, тем самым помогая программистам избежать распространенных ошибок управления памятью, таких как утечки памяти, висячие указатели и другие проблемы.

Интеллектуальные указатели работают через механизм инициализации сбора ресурсов (RAII), который означает, что интеллектуальные указатели получают ресурсы при их создании и освобождают ресурсы при их уничтожении. Это гарантирует правильное высвобождение ресурсов даже в аномальных обстоятельствах.

 

Проблемы, решаемые с помощью умных указателей

(1) Утечка памяти: память освобождается вручную, но ее можно освободить автоматически с помощью интеллектуальных указателей.

(2) Распространение и выпуск указателей общего владения, например проблемы уничтожения, когда несколько потоков используют один и тот же объект.

 

Несколько типов умных указателей

Стандартная библиотека C++ предоставляет несколько типов интеллектуальных указателей, в том числе:

  1. std::unique_ptr

    • исключительная модель владения, то естьunique_ptrЭкземпляр имеет исключительное право собственности на объект, на который он указывает.
    • когдаunique_ptrКогда он выходит за пределы области видимости или явно сбрасывается, он автоматически вызывает деструктор и освобождает управляемый объект.
    • Копирование не поддерживается, но перемещение возможно.
  2. std::shared_ptr

    • Модель совместной собственности, позволяющая несколькимshared_ptrЭкземпляры совместно владеют одним и тем же объектом.
    • Используйте подсчет ссылок для отслеживания ссылок на один и тот же объект.shared_ptrколичество.
    • когда последнийshared_ptrКогда экземпляр выходит за пределы области видимости или сбрасывается, счетчик ссылок уменьшается до нуля, вызывается деструктор объекта и объект освобождается.
  3. std::weak_ptr

    • используется для решенияshared_ptrПроблема циклической ссылки.
    • Без увеличения счетчика ссылок это можно наблюдать с помощьюshared_ptrуправляемые объекты, но не участвует в управлении их жизненным циклом.
    • Когда нетshared_ptrКогда экземпляр указывает на объект,weak_ptrМожет обнаружить, что объект был уничтожен.

Разработка и использование интеллектуальных указателей значительно упрощает управление памятью в C++ и повышает надежность и безопасность программы. В современном программировании на C++ настоятельно рекомендуется использовать интеллектуальные указатели вместо необработанных указателей, чтобы улучшить качество и удобство сопровождения кода.

 

Пример умного указателя

Интеллектуальные указатели используются в C++ как средство автоматического управления динамически выделяемой памятью для предотвращения утечек памяти и других проблем, связанных с управлением ресурсами.

std::unique_ptrПример

std::unique_ptr— это интеллектуальный указатель с исключительным правом владения, который гарантирует, что существует только одинstd::unique_ptr Экземпляр имеет контроль над данным ресурсом.когдаstd::unique_ptrКогда он выходит за пределы области действия или сбрасывается, ресурсы, которыми он владеет, будут автоматически освобождены.

  1. #include <memory>
  2. class MyClass {
  3. public:
  4. MyClass() { std::cout << "MyClass constructor called.n"; }
  5. ~MyClass() { std::cout << "MyClass destructor called.n"; }
  6. void doSomething() { std::cout << "Doing something...n"; }
  7. };
  8. int main() {
  9. // 创建一个unique_ptr来管理MyClass的实例
  10. std::unique_ptr<MyClass> uptr(new MyClass());
  11. // 调用doSomething方法
  12. uptr->doSomething();
  13. // unique_ptr会在离开作用域时自动调用MyClass的析构函数
  14. return 0;
  15. }

std::shared_ptrПример

std::shared_ptr— это интеллектуальный указатель с совместным владением, который позволяет несколькимstd::shared_ptrЭкземпляры совместно владеют одним и тем же ресурсом.std::shared_ptrИспользуйте счетчик ссылок, чтобы отслеживать, сколько интеллектуальных указателей указывают на один и тот же ресурс. Когда счетчик ссылок достигает 0, ресурс освобождается.

  1. #include <memory>
  2. class MyClass {
  3. public:
  4. MyClass() { std::cout << "MyClass constructor called.n"; }
  5. ~MyClass() { std::cout << "MyClass destructor called.n"; }
  6. void doSomething() { std::cout << "Doing something...n"; }
  7. };
  8. int main() {
  9. // 创建一个shared_ptr来管理MyClass的实例
  10. std::shared_ptr<MyClass> sptr(new MyClass());
  11. // 创建第二个shared_ptr,共享同一个MyClass实例
  12. std::shared_ptr<MyClass> sptr2 = sptr;
  13. // 调用doSomething方法
  14. sptr->doSomething();
  15. // 当所有shared_ptr实例都超出作用域时,MyClass的析构函数才会被调用
  16. return 0;
  17. }

 

Меры предосторожности

В использованииstd::shared_ptr При этом будьте осторожны, чтобы избежать ситуаций циклических ссылок, которые приведут к тому, что счетчик ссылок никогда не упадет до 0, что приведет к утечкам ресурсов.В случае циклических ссылок вы можете использоватьstd::weak_ptrразорвать порочный круг,std::weak_ptrНе увеличивает счетчик ссылок, а только сохраняетstd::shared_ptrУправляйте слабыми ссылками на ресурсы.

В этих примерах показано, как использовать интеллектуальные указатели для управления динамически выделяемой памятью, чтобы гарантировать правильное высвобождение ресурсов в нужное время и избежать распространенных ошибок, которые могут возникнуть при ручном управлении памятью.

 

Другие примеры

https://www.cnblogs.com/god-of-death/p/17962676

https://zhuanlan.zhihu.com/p/678722914