기술나눔

【C】스마트 포인터

2024-07-12

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

스마트 포인터 설명

스마트 포인터는 동적으로 할당된 메모리를 자동으로 관리하는 데 사용되는 C++ 도구입니다.

원시 포인터의 기능을 캡슐화하고 리소스 할당 및 해제를 자동으로 처리할 수 있는 클래스로, 이를 통해 프로그래머는 메모리 누수, 매달린 포인터 및 기타 문제와 같은 일반적인 메모리 관리 오류를 피할 수 있습니다.

스마트 포인터는 RAII(Resource Acquisition Is 초기화) 메커니즘을 통해 작동합니다. 즉, 스마트 포인터는 생성될 때 리소스를 획득하고 소멸될 때 리소스를 해제합니다. 이렇게 하면 비정상적인 상황에서도 리소스가 올바르게 해제됩니다.

 

스마트 포인터로 해결되는 문제

(1) 메모리 누수: 메모리를 수동으로 해제하지만 스마트 포인터를 사용하면 자동으로 해제할 수 있습니다.

(2) 여러 스레드가 동일한 객체를 사용할 때 소멸 문제와 같은 공유 소유권 포인터의 전파 및 해제.

 

여러 유형의 스마트 포인터

C++ 표준 라이브러리는 다음을 포함하여 여러 유형의 스마트 포인터를 제공합니다.

  1. std::unique_ptr

    • 독점 소유권 모델, 즉unique_ptr인스턴스는 자신이 가리키는 개체에 대한 독점 소유권을 갖습니다.
    • 언제unique_ptr범위를 벗어나거나 명시적으로 재설정되면 자동으로 소멸자를 호출하고 관리되는 개체를 해제합니다.
    • 복사는 지원되지 않으나 이동은 가능합니다.
  2. std::shared_ptr

    • 공유 소유권 모델, 다중 허용shared_ptr인스턴스는 동일한 객체의 소유권을 공유합니다.
    • 참조 계산을 사용하여 동일한 객체에 대한 참조 추적shared_ptr수량.
    • 마지막 때shared_ptr인스턴스가 범위를 벗어나거나 재설정되면 참조 횟수가 0으로 줄어들고 개체의 소멸자가 호출되며 개체가 해제됩니다.
  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