C++ 没有垃圾回收,因此 new 出来的对象都要自己管理

为了方便的管理内存,我们发现垃圾回收中引用计数的思路很简单就能在 C++ 中实现,而其实标准库中就已经有这样的实现,也就是智能指针

它们的头文件都是 memory

shared_prt

根据引用计数自动销毁对象,构造时引用数加一,析构时引用数减一,为零就销毁

void Func(shared_ptr<string> ptr) {
    printf("%ld\n", ptr.use_count());
    auto ptr2 = ptr;
    printf("%ld\n", ptr.use_count());
}

int main() {
    auto ptr = make_shared<string>("Hello shared ptr");
    printf("%ld\n", ptr.use_count());
    Func(ptr);
    printf("%ld\n", ptr.use_count());
    return 0;
}

weak_ptr

有时候我们希望获得一个使用 shared_ptr 管理的对象,但是又不希望影响原本 shared_ptr 的生命期,此时就可以使用 weak_ptr

它不会改变引用计数,可以查询是否被销毁,另外也可以调用 lock 方法来获取 shared_ptr 续命

把上面的例子修改一下

void Func(weak_ptr<string> ptr) {
    printf("%ld\n", ptr.use_count());
    auto ptr2 = ptr.lock();
    printf("%ld\n", ptr.use_count());
}

int main() {
    auto ptr = make_shared<string>("Hello shared ptr");
    printf("%ld\n", ptr.use_count());
    Func(ptr);
    printf("%ld\n", ptr.use_count());
    return 0;
}

unique_ptr

可以理解为特殊的 shared_ptr,它的引用数至多为一,拷贝构造函数也被禁用

如果想要转移一个使用 unique_ptr 管理的对象,需要 move

int main() {
    auto ptr = make_unique<string>("Hello shared ptr");
    printf("%s\n", ptr->c_str());
    auto ptr2 = move(ptr);
    printf("%s\n", ptr2->c_str());
    return 0;
}