C++/Library 2021. 3. 24. 10:47

shared_ptr

shared_ptr

  • <memory> 라이브러리

  • 몇 개의 변수가 포인터를 참조하고 있는지 내부적으로 계산한다.


예제

main.cpp

  #include <iostream>
  #include <memory>
  #include "Resource.h"

  int            main()
  {
    Resource* res = new Resource(3);
    res->setAll(1);

    {
      std::shared_ptr<Resource> ptr1(res);

      ptr1->print();

      {
        std::shared_ptr<Resource> ptr2(ptr1);

        ptr2->setAll(3);
        ptr2->print();

        std::cout << "Going out of the block\n";
      }

      ptr1->print();
      std::cout << "Going out of the outer block\n";
    }
    std::cout << "Last of main function\n";
  }

  /* stdout stderr
  Resource length constructed
  1 1 1
  3 3 3
  Going out of the block
  3 3 3
  Going out of the outer block
  Resource destoryed
  Last of main function
  */

Resource.h

  #pragma once

  #include <iostream>

  class Resource
  {
  public:
    int    *data_ = nullptr;
    unsigned length_ = 0;

    Resource()
    {
      std::cout << "Resource default constructed\n";
    }

    Resource(unsigned length)
    {
      std::cout << "Resource length constructed\n";
      init(length);
    }

    Resource(const Resource& res)
    {
      std::cout << "Resource copy constructed\n";
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
    }

    ~Resource()
    {
      std::cout << "Resource destoryed\n";

      if (data_ != nullptr) delete[] data_;
    }

    void    init(unsigned length)
    {
      data_ = new int[length];
      length_ = length;
    }

    Resource& operator = (Resource& res)
    {
      std::cout << "Resource copy assignment\n";
      if (&res == this) return *this;

      if (data_ != nullptr) delete[] data_;
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
      return *this;
    }

    void    print()
    {
      for (unsigned i = 0; i < length_; ++i)
        std::cout << data_[i] << ' ';
      std::cout << std::endl;
    }

    void    setAll(const int& v)
    {
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = v;
    }
  };
  • 아래와 같이 ptr2를 생성하면 ptr1에서 알 수 없기 때문에 에러가 발생한다.

    std::shared_ptr<Resource> ptr2(res);
  • make_shared를 사용해서 직접 초기화하는 방법이 일반적이다.

    main.cpp

    #include <iostream>
    #include <memory>
    #include "Resource.h"
    
    int            main()
    {
      {
        auto ptr1 = std::make_shared<Resource>(3);
        ptr1->setAll(1);
        ptr1->print();
    
        {
          auto ptr2 = ptr1;
    
          ptr2->setAll(3);
          ptr2->print();
    
          std::cout << "Going out of the block\n";
        }
    
        ptr1->print();
        std::cout << "Going out of the outer block\n";
      }
      std::cout << "Last of main function\n";
    }
    
    /* stdout stderr
    Resource length constructed
    1 1 1
    3 3 3
    Going out of the block
    3 3 3
    Going out of the outer block
    Resource destoryed
    Last of main function
    */

'C++ > Library' 카테고리의 다른 글

C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)  (0) 2021.03.24
C++ weak_ptr  (0) 2021.03.24
C++ unique_ptr  (0) 2021.03.24
C++ std::move  (0) 2021.03.24
C++ 출력 스트림 끊기  (0) 2021.03.24