why?

    class A {
    public:
        A() { std::cout << "A ctor" << std::endl;}
        ~A() { std::cout << "A dtor" << std::endl; }

        std::shared_ptr<B> spB;
    };

    class B {
    public:
        B() { std::cout << "B ctor" << std::endl;}
        ~B() { std::cout << "B dtor" << std::endl; }

        std::shared_ptr<A> spA;
    };

    int main() {
        std::shared_ptr<A> spA = std::make_shared<A>();
        std::shared_ptr<B> spB = std::make_shared<B>();

        spA->spB_ = spB;
        spB->spA_ = spA;

        return 0;
    }

    output:
    A ctor
    B ctor

从以上结果可以看出,A、B均未释放,造成内存泄漏。 根本原因在于,A、B之间的循环引用。

how?

weak_ptr用来与shared_ptr共同使用,避免内存泄漏。

    class A {
    public:
        A() { std::cout << "A ctor" << std::endl;}
        ~A() { std::cout << "A dtor" << std::endl; }

        void foo() {
            std::cout << "I am foo" << std::endl;
        }

        std::weak_ptr<B> wpB_;
    };

    class B {
    public:
        B() { std::cout << "B ctor" << std::endl;}
        ~B() { std::cout << "B dtor" << std::endl; }

        std::weak_ptr<A> wpA_;
    };

    int main() {
        std::shared_ptr<A> spA = std::make_shared<A>();
        std::shared_ptr<B> spB = std::make_shared<B>();

        spA->wpB_ = spB;
        spB->wpA_ = spA;

        spB->wpA_.lock()->foo();

        return 0;
    }

    output:
    A ctor
    B ctor
    I am foo
    B dtor
    A dtor

总结

  1. weak_ptr不会使指针引用计数增加,它只是一个“观察者”
  2. weak_ptr没有重载operator*和->,因为它不共享指针,不能操作资源
  3. weak_ptr提供了expired()与lock()成员函数
  4. expired()用于判断weak_ptr指向的对象是否已被销毁
  5. lock()返回其所指对象的shared_ptr智能指针