std::shared_ptr

  • Smart pointers are used to make sure that an object can be deleted when it is no longer used. 😍
  • 系统会自动释放。
  • Several shared pointers can share/point to the same object.
  • The object is destroyed when no shared_ptr points to it.
    • 如果没有指针指向,该指针就会自动删除 ```cpp

      include

      include

class MyTime { int hours; int minutes;

public: MyTime() : hours(0), minutes(0) { std::cout << “Constructor MyTime()” << std::endl; } MyTime(int m) : hours(0), minutes(m) { std::cout << “Constructor MyTime(int)” << std::endl; this->hours += this->minutes / 60; this->minutes %= 60; } MyTime(int h, int m) : hours(h), minutes(m) { std::cout << “Constructor MyTime(int,int)” << std::endl; this->hours += this->minutes / 60; this->minutes %= 60; } ~MyTime() { std::cout << “Destructor MyTime(). Bye!” << std::endl; } MyTime operator+(int m) const { MyTime sum; sum.minutes = this->minutes + m; sum.hours = this->hours; sum.hours += sum.minutes / 60; sum.minutes %= 60; return sum; } friend std::ostream &operator<<(std::ostream &os, const MyTime &t) { std::string str = std::to_string(t.hours) + “ hours and “ + std::to_string(t.minutes) + “ minutes.”; os << str; return os; } };

int main() { // std::shared_ptr mt0 = new MyTime(0,70); //error // MyTime mt1 = std::make_shared(1, 70); //error // { // std::shared_ptr mt1(new MyTime(10)); // std::cout << mt1 << std::endl; // }

  1. {
  2. std::shared_ptr<MyTime> mt1 = std::make_shared<MyTime>(1, 70);
  3. std::shared_ptr<MyTime> mt2 = mt1;
  4. std::shared_ptr<MyTime> mt3 = mt2;
  5. std::cout << "mt1: " << *mt1 << std::endl;
  6. std::cout << "mt2: " << *mt2 << std::endl;
  7. std::cout << "mt3: " << *mt3 << std::endl;
  8. std::cout << "use_count() = " << mt2.use_count() << std::endl;
  9. {
  10. auto mt4 = mt3;
  11. *mt4 = *mt4 + 50;
  12. std::cout << "use_count() = " << mt3.use_count() << std::endl;
  13. }
  14. std::cout << "mt3: " << *mt3 << std::endl;
  15. std::cout << "use_count() = " << mt3.use_count() << std::endl;
  16. }
  17. return 0;

}

<a name="XbDzr"></a>
## std::unique_ptr

- Different from `std::shared_ptr`, a `std::unique_ptr` **will point to an object, and not allow others to point to.**
- But an object pointed by a std::unique_ptr can be moved to another pointer.
```cpp
#include <iostream>
#include <memory>

class MyTime
{
    int hours;
    int minutes;

public:
    MyTime() : hours(0), minutes(0)
    {
        std::cout << "Constructor MyTime()" << std::endl;
    }
    MyTime(int m) : hours(0), minutes(m)
    {
        std::cout << "Constructor MyTime(int)" << std::endl;
        this->hours += this->minutes / 60;
        this->minutes %= 60;
    }
    MyTime(int h, int m) : hours(h), minutes(m)
    {
        std::cout << "Constructor MyTime(int,int)" << std::endl;
        this->hours += this->minutes / 60;
        this->minutes %= 60;
    }
    ~MyTime()
    {
        std::cout << "Destructor MyTime(). Bye!" << std::endl;
    }
    MyTime operator+(int m) const
    {
        MyTime sum;
        sum.minutes = this->minutes + m;
        sum.hours = this->hours;
        sum.hours += sum.minutes / 60;
        sum.minutes %= 60;
        return sum;
    }
    friend std::ostream &operator<<(std::ostream &os, const MyTime &t)
    {
        std::string str = std::to_string(t.hours) + " hours and " + std::to_string(t.minutes) + " minutes.";
        os << str;
        return os;
    }
};

int main()
{
    std::unique_ptr<MyTime> mt1(new MyTime(10));
    std::unique_ptr<MyTime> mt2 = std::make_unique<MyTime>(80); // c++17

    std::cout << "mt1: " << *mt1 << std::endl;
    std::cout << "mt2: " << *mt2 << std::endl;

    // std::unique_ptr<MyTime> mt3 = mt1; // error
    std::unique_ptr<MyTime> mt3 = std::move(mt1);
    // std::shared_ptr<MyTime> mt3 = std::move(mt1);//okay

    // std::cout << "mt1: " <<*mt1 << std::endl;
    std::cout << "mt3: " << *mt3 << std::endl;

    return 0;
}

How to Understand Smart Pointers

Let’s look at their definitions.

template< class T > class shared_ptr;

template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
  • mt1 and mt2 are two objects of type shared_ptr<>.
    • You can do a lot in the constructors and the destructor.
      std::shared_ptr<MyTime> mt1(new MyTime(10));
      std::shared_ptr<MyTime> mt2 = mt1;