是否有共享引用计数智能指针这样的东西?

时间:2012-11-29 06:01:07

标签: c++ boost smart-pointers raii reference-counting

使用boost::shared_ptr的程序员需要避免循环,以免创建资源泄漏。一般建议是在可能创建此类循环的情况下使用boost::weak_ptr。但是这样做会产生意图上的差距,人们可能更倾向于使用shared_ptr,但仅仅因为循环问题而没有这样做。

在我看来,应该可以创建一种特殊的shared_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;
}

一般的概念是,在想象shared_count_ptr的眼中,手臂和手是实际上相同的对象。

所以:

  • 这种想法是否已存在于boost
  • 如果没有,是因为这是一个糟糕的主意吗?(或者我只是想出一些聪明的东西?)

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

我会想象你可以沿着这些方向做某事。但是,在这样的结构中,每个指针A都需要知道每个其他指针B,这样B可以从A到达,反之亦然。我没有看到它如何可以扩展到更多的互连指针。

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