Compartilhamento de tecnologia

【C】Ponteiro inteligente

2024-07-12

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

Ponteiros inteligentes explicados

Smart Pointer é uma ferramenta em C++ usada para gerenciar automaticamente a memória alocada dinamicamente.

É uma classe que encapsula as funções de ponteiros brutos e pode lidar automaticamente com a alocação e liberação de recursos, ajudando assim os programadores a evitar erros comuns de gerenciamento de memória, como vazamentos de memória, ponteiros pendentes e outros problemas.

Os ponteiros inteligentes funcionam por meio do mecanismo Resource Acquisition Is Initialization (RAII), o que significa que os ponteiros inteligentes adquirem recursos quando são construídos e liberam recursos quando são destruídos. Isto garante que os recursos sejam liberados corretamente, mesmo em circunstâncias anormais.

 

Problemas resolvidos por ponteiros inteligentes

(1) Vazamento de memória: A memória é liberada manualmente, mas pode ser liberada automaticamente usando ponteiros inteligentes.

(2) Propagação e liberação de ponteiros de propriedade compartilhada, como problemas de destruição quando vários threads usam o mesmo objeto.

 

Vários tipos de ponteiros inteligentes

A biblioteca padrão C++ fornece vários tipos de ponteiros inteligentes, incluindo:

  1. std::unique_ptr

    • modelo de propriedade exclusiva, ou seja, umunique_ptrUma instância tem propriedade exclusiva do objeto para o qual aponta.
    • quandounique_ptrQuando sai do escopo ou é redefinido explicitamente, ele chama automaticamente o destruidor e libera o objeto gerenciado.
    • A cópia não é suportada, mas a movimentação é possível.
  2. std::shared_ptr

    • Modelo de propriedade compartilhada, permitindo múltiplosshared_ptrAs instâncias compartilham a propriedade do mesmo objeto.
    • Use a contagem de referências para rastrear referências ao mesmo objetoshared_ptrquantidade.
    • quando o últimoshared_ptrQuando uma instância sai do escopo ou é redefinida, a contagem de referências é reduzida a zero, o destruidor do objeto é chamado e o objeto é liberado.
  3. std::weak_ptr

    • usado para resolvershared_ptrproblema de referência circular.
    • Sem incrementar a contagem de referência, isso pode ser observado porshared_ptrobjetos gerenciados, mas não participa do gerenciamento do seu ciclo de vida.
    • Quando não háshared_ptrQuando uma instância aponta para um objeto,weak_ptrPode detectar que o objeto foi destruído.

O design e o uso de ponteiros inteligentes simplificam muito o gerenciamento de memória em C++ e melhoram a robustez e a segurança do programa. Na programação C++ moderna, é altamente recomendável usar ponteiros inteligentes em vez de ponteiros brutos para melhorar a qualidade e a capacidade de manutenção do código.

 

Exemplo de ponteiro inteligente

Ponteiros inteligentes são usados ​​em C++ como um meio de gerenciar automaticamente a memória alocada dinamicamente para evitar vazamentos de memória e outros problemas relacionados ao gerenciamento de recursos.

std::unique_ptrExemplo

std::unique_ptré um ponteiro inteligente com propriedade exclusiva, que garante que haja apenas umstd::unique_ptr Uma instância tem controle sobre um determinado recurso.quandostd::unique_ptrQuando sair do escopo ou for redefinido, os recursos de sua propriedade serão liberados automaticamente.

  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_ptrExemplo

std::shared_ptré um ponteiro inteligente de propriedade compartilhada que permite váriosstd::shared_ptrAs instâncias compartilham a propriedade do mesmo recurso.std::shared_ptrUse uma contagem de referência para rastrear quantos ponteiros inteligentes apontam para o mesmo recurso. Quando a contagem de referência atingir 0, o recurso será liberado.

  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. }

 

Precauções

Em usostd::shared_ptr Ao fazer isto, tenha cuidado para evitar situações de referência circular, o que fará com que a contagem de referência nunca caia para 0, levando a fugas de recursos.No caso de referências circulares, você pode usarstd::weak_ptrpara quebrar o ciclo,std::weak_ptrNão incrementa a contagem de referência, apenas mantém ostd::shared_ptrGerencie referências fracas a recursos.

Estes exemplos mostram como usar ponteiros inteligentes para gerenciar memória alocada dinamicamente para garantir que os recursos sejam liberados adequadamente no momento apropriado, evitando erros comuns que podem ocorrer ao gerenciar manualmente a memória.

 

Outros exemplos

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

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