为unique_ptr引用refcount的替代方法

时间:2016-06-28 07:22:16

标签: c++ c++11 smart-pointers

在下面的代码示例中,只要A的任何对象存在,struct B中就应该存在struct B的一个实例。示例按预期工作。

#include <memory>
#include <iostream>
#include <mutex>

struct A
{
    A() { std::cout << "A() called" << std::endl; }
    ~A() { std::cout << "~A() called" << std::endl; }
};

struct B
{
    B()
    {
        std::cout << "B() called" << std::endl; 

        std::lock_guard<std::mutex> guard(mtx);
        if( !refCount )
        {
            a.reset( new A ); 
        }
        ++refCount;
    }

    ~B()
    {
        std::cout << "~B() called" << std::endl;
        std::lock_guard<std::mutex> guard(mtx);
        --refCount;
        if( !refCount )
        {
            a.reset( ); 
        }
    }

    static std::unique_ptr<A> a;
    static std::mutex mtx;
    static int refCount;
};

std::unique_ptr<A> B::a;
int B::refCount(0);
std::mutex B::mtx;

int main()
{
    {
        B b1; //B::a should be created here
        B b2;
    } //B::a should be destroyed here

    B b3; // B::a should be recreated here
} //B::a should be destroyed again here

另见http://coliru.stacked-crooked.com/a/fea428254933ee5c

我的问题:是否有一个没有引用计数的替代(线程安全!)实现?这可能是用std::shared_ptrstd::weak_ptr的结构来解决的吗?

2 个答案:

答案 0 :(得分:4)

确保对象“只要Icon1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("clicled", String.valueOf(position)); Icon1.setImageResource(R.drawable.icon1_active); Icon2.setImageResource(R.drawable.icon2_unactive);}}); Icon2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Icon1.setImageResource(R.drawable.icon1_unactive); Icon2.setImageResource(R.drawable.icon2_active);}); 的任何对象生存”的唯一方法是保留B个对象的引用计数。这是判断是否有任何活B个对象的唯一现实方法,如果它们随着程序的运行而被随意创建和销毁。

B内部保留了refcounts,这些都是原子跟踪的。使用它们可能是更好的主意,而不是自己手动管理引用计数;这样你就不必一丝不苟地实现所有RAII构造函数,或者重新发明轮子。

答案 1 :(得分:1)

这是想要的解决方案:

#include <memory>
#include <iostream>
#include <mutex>
using std::shared_ptr;
using std::weak_ptr;

struct A
{
    A() { std::cout << "A() called" << std::endl; }
    ~A() { std::cout << "~A() called" << std::endl; }
};

struct B
{
    B()
    {   std::cout << "B() called" << std::endl;
        std::lock_guard<std::mutex> guard(mtx);
        if (!(ac =aw.lock()))
          aw =ac =shared_ptr<A>(new A);
    }

    ~B()
    {   std::cout << "~B() called" << std::endl;
    }
    shared_ptr<A> ac;
    static weak_ptr<A> aw;
    static std::mutex mtx;
};
weak_ptr<A> B::aw;
std::mutex B::mtx;

int main()
{
    {
        B b1; //B::a should be created here
        B b2;
    } //B::a should be destroyed here

    B b3; // B::a should be recreated here
} //B::a should be destroyed again here

产生与您的示例相同的输出:

B() called
A() called
B() called
~B() called
~B() called
~A() called
B() called
A() called
~B() called
~A() called