C++ 是否存在共享引用计数智能指针?

C++ 是否存在共享引用计数智能指针?,c++,boost,smart-pointers,raii,reference-counting,C++,Boost,Smart Pointers,Raii,Reference Counting,使用boost::shared_ptr的程序员需要避免周期,以免造成资源泄漏。一般建议在可能产生这种循环的情况下使用boost::weak_ptr。然而,这样做会造成意图上的差距,人们可能更愿意使用共享\u ptr,但仅仅因为周期问题而没有这样做 不过,在我看来,应该可以创建一种特殊的共享ptr,通过链接循环中所有指针的引用计数来避免循环问题。既然我能想出一个办法,我想知道这样的事情是否存在 为了证明我不是疯子,或者也许我是,我提供了以下经过深思熟虑的丑陋的概念证明: #define BOOST

使用
boost::shared_ptr
的程序员需要避免周期,以免造成资源泄漏。一般建议在可能产生这种循环的情况下使用
boost::weak_ptr
。然而,这样做会造成意图上的差距,人们可能更愿意使用
共享\u ptr
,但仅仅因为周期问题而没有这样做

不过,在我看来,应该可以创建一种特殊的共享ptr,通过链接循环中所有指针的引用计数来避免循环问题。既然我能想出一个办法,我想知道这样的事情是否存在

为了证明我不是疯子,或者也许我是,我提供了以下经过深思熟虑的丑陋的概念证明:

#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS

#include <boost/shared_ptr.hpp>
#include <iostream>

template <typename T>
struct shared_count_ptr
{
    boost::shared_ptr<T> innerPtr;
    template <typename TT>
    void link( boost::shared_ptr<T> & sharedPtr, boost::shared_ptr<TT> & linked )
    {
        innerPtr    = sharedPtr;
        innerPtr.pn = linked.pn;
    }
};

struct Hand;
struct Arm
{
    Arm()  { std::cout << "Creating Arm\n";   }
    ~Arm() { std::cout << "Destroying Arm\n"; }

    shared_count_ptr<Hand> hand;
};

struct Hand
{
    Hand()  { std::cout << "Creating Hand\n";   }
    ~Hand() { std::cout << "Destroying Hand\n"; }

    shared_count_ptr<Arm> arm;
};

int main()
{
    boost::shared_ptr<Arm> savedArm;

    std::cout << "Scope 0 entered\n";
    {
        std::cout << "\tScope 1 entered\n" ;

        boost::shared_ptr<Arm> arm( new Arm );
        {
            std::cout << "\t\tScope 2 entered\n";
            boost::shared_ptr<Hand>  hand( new Hand );

            hand->arm.link( arm, arm->hand );
            arm->hand.innerPtr = hand;

            savedArm = arm;
        }
        std::cout << "\t\tScope 2 exited\n";
    }
    std::cout << "\tScope 1 exited\n";
    std::cout << "\tScope 0 about to exit\n";

    return 0;
}
#定义BOOST_NO_MEMBER_TEMPLATE_FRIENDS
#包括
#包括
模板
结构共享\u计数\u ptr
{
boost::shared_ptr innerPtr;
模板
无效链接(boost::shared_ptr&sharedPtr,boost::shared_ptr&linked)
{
innerPtr=共享DPTR;
innerPtr.pn=linked.pn;
}
};
结构手;
结构臂
{
Arm(){std::cout我想你可以按照这些思路做些事情。然而,在这样的结构中,每个指针
a
都需要知道其他每个指针
B
,这样
B
可以从
a
中访问,或者反之亦然。我不知道这怎么可能扩展到超过一小部分互连指针


似乎如果您想在没有程序员帮助的情况下支持循环引用,您或多或少需要一个全面的垃圾收集器,而不是一个简单的引用计数方案(我希望在这方面被证明是错误的).

这里有一个简单的测试。在17个顶点上创建一个完整的图,这样程序就只指向顶点0。开始随机删除边。你的想法行吗?(剧透:不行)。

我无法想象需要做一些小改动就可以很容易地避免。我认为主要的问题是有时候(或经常)您可能不希望同时创建指针,这可能会使它变得更加复杂。或者强制程序员显式链接指针只是自找麻烦。请注意,您的shared_count_ptr类可能不应该有shared_ptr成员,因为它已经继承了它,除非我误解了您的设计继承是从is-a中遗留下来的,将要从has-a中修复。我确信有更好的方法来实现这一点,这将不会太难看。我想如果您的算法使用链表而不是简单的共享整数计数器,您可以检测循环。也就是说,没有匹配的
取消链接
,也不可能编写一个。也许对m来说不是这样例如,y straw man,但我相信这将有助于更周密的实施。欢迎您尝试并提出一个方案。我不会屏住呼吸。您可能是对的。我无法花费大量时间进行更多调查。但是我的个人用例处于静态关系中,因此删除链接d关系并不重要。引用计数方案本身不可能检测周期,至少不需要程序员的一些输入。如果您愿意提供这样的输入,当然是可能的。使用运行时可选策略制作智能指针(在强类型和弱类型之间选择)。这与您所拥有的大致相同,但界面更简单。一般概念(我的示例可能无法很好地表示)你应该能够区分引用计数和被指向的类型。从概念上讲,它应该可以扩展,智能指针也可以扩展到同一个对象。循环检测当然需要全面的垃圾收集。我的建议是,如果作者知道开始的循环,它应该我们有可能利用这些知识来避免问题。