智能指针的计数器减量如何工作?

时间:2016-07-03 06:27:04

标签: c++ shared-ptr smart-pointers

下面是共享指针的示例代码。我在花括号范围内定义了一个共享指针。 sp1由新的A(计数器= 1)初始化,sp1分配给sp2(复制和/或赋值将计数器增加1,因此,计数器= 2)。我总是认为当计数器变为0时,会调用A的析构函数。但在我的情况下,智能指针何时即将超出范围(通过大括号),计数器为2。

我的问题是:谁将计数器从2改为0?

#include <iostream>
#include <memory>

using namespace std;

class A{
public:
    ~A(){

        std::cout << "~A" <<  std::endl;
    }    
};
int main(){
    {
        shared_ptr<A> sp1 (new A); 
        shared_ptr<A> sp2 = sp1;

        std::cout << "sp1 count = " << sp1.use_count() << std::endl;
        std::cout << "sp2 count = " << sp2.use_count() << std::endl;
    }

return 0;
}

修改      链接到smart pointer

上的论文

输出:

  

sp1 count = 2

     

sp2 count = 2

     

〜A

2 个答案:

答案 0 :(得分:4)

当你的代码到达main的末尾时,sp1sp2的析构函数都会运行,这会将计数器递减为零 - 这是共享指针的一个非常重要的部分,即析构函数减少参考计数,因此,什么时候没有&#34;没有&#34;留下,实际共享对象的析构函数被调用。

shared_ptr的指责者会有这样的逻辑:

 counter--;    // Should be atomic!
 if (counter == 0)
 {
    delete owned_thing;
 }

答案 1 :(得分:4)

更好的例子(IMO)将是这样的:

int main()
{
    std::shared_ptr<A> sp1{new A};
    std::cout << "1: sp1.use_count() = " << sp1.use_count() << '\n';

    {
        std::shared_ptr<A> sp2 = sp1;
        std::cout << "2: sp1.use_count() = " << sp1.use_count() << '\n';
        std::cout << "2: sp2.use_count() = " << sp2.use_count() << '\n';
    }

    std::cout << "3: sp1.use_count() = " << sp1.use_count() << '\n';
}

这个程序的输出应该是(使用你的类及其析构函数):

1: sp1.use_count() = 1
2: sp1.use_count() = 2
2: sp2.use_count() = 2
3: sp1.use_count() = 1
~A

首先创建一个共享指针并对其进行初始化,然后使用计数器1。然后输入一个新的作用域,并在其中创建一个新的共享指针,使用旧指针初始化它(使用共享指针copy-constructor),导致两个指针的使用计数为2。然后第二个共享指针超出范围,共享指针析构函数将使用计数减1。最后,当main函数返回时,第二个共享指针超出范围,并且使用计数由sp1析构函数递减。现在它已经达到零,并且删除了包含的指针,导致调用A析构函数。