当 class 被另一个 class 引用并使用吸气剂时,计数器如何工作

How does the counters work when a class is referenced by another class and with getters

问题描述

我想了解 shared_ptr 计数器的工作原理。在我的 class A 中,当我使用 getter 时,计数器递增 1。当在 class B 中使用 A 的实例时,计数器增加 2。当我完成 class B 时,A 的析构函数被调用了两次。

我不明白和困惑的是以下内容:


源代码

    #include <iostream>
    #include <memory>
    
    using namespace std;
    
    class A {
        public:
        A(int a):_a( make_shared<int>(a)) {cout <<"A constructor" << endl;}
        ~A(){/*_a.reset();*/cout <<"After destructor, number of As "<< _a.use_count() <<endl;}
        std::shared_ptr<int> a(){return _a;}
        //private:
         std::shared_ptr<int> _a;
    };
    
    class B {
        public:
        B(A a):_b( make_shared<A>(a)) {cout <<"B constructor" << endl;}
        ~B(){ /*_b.reset();*/ cout <<"After destructor, number of Bs "<< _b.use_count() << endl;}
         std::shared_ptr<A> b(){return _b;}
        private:
          std::shared_ptr<A> _b;
    };
    
    
    
    int main()
    {  
        int number = 10;
        A a(number);
        cout <<"counter of A is " << a._a.use_count() << endl;
        cout <<"counter of A is " << a.a().use_count() << endl;
        
        B b(a);
        cout <<"counter of A is " << a.a().use_count() << endl;
        cout <<"counter of B is " << b.b().use_count() << endl;
        
        return 0;
}

  A--->Number: Counter = 1
  B(constructor) pass A by value : counter = 2
  B--->Number: Counter = 3

不复位输出

一个构造函数
A 的计数器是 1
A 的计数器是 2
B构造函数
析构函数后,As 的个数 3
A 的计数器是 3
B 的计数器是 2
析构后,Bs个数1
析构后,As 的个数 2
析构函数后,As 的个数 1

带重置的输出

一个构造函数
A 的计数器是 1
A 的计数器是 2
B构造函数
析构函数后,As 的个数 0
A 的计数器是 3
B 的计数器是 2
析构函数后,As 的个数 0
析构后,Bs个数0
析构函数后,As 的个数 0

快速回答

  • 每次调用 a.a() 时,它 return 都是一个指向资源的新共享指针。第一个是成员变量。它们最终会被释放,但没有任何保证,因为您没有将 returned 共享指针存储到变量中(这会将它绑定到一个范围)。
  • 第一个 After destructor, ... 是因为您将 A a 的值复制到 B 的构造函数中。如果您希望避免复制,则使用引用 B(A& a).
  • 数字 3 是因为三个 shared_pointers、A a 内部一个、return 编辑但未发布 a.a() 结果以及 [=12] 的副本=] 传递给 B.
  • 的构造函数
  • 在 class B 中,您还在 b.b() 中 return 新的共享指针 -> 将计数器递增 1。

我希望这涵盖了你所有的问题,如果你有任何问题,我可以尝试进一步澄清。