1

使用的程序员boost::shared_ptr需要避免循环,以免造成资源泄漏。一般建议是boost::weak_ptr在可能创建此类循环的情况下使用 a 。然而,这样做会造成意图上的差距,人们可能更喜欢使用 ashared_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
  • 如果不是,是不是因为这是一个糟糕的主意?(或者我只是想出了一些聪明的东西?)
4

2 回答 2

2

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

于 2012-11-29T08:59:27.217 回答
1

我想你可以按照这些思路做一些事情。但是,在这样的结构中,每个指针都A需要了解每个其他指针B,以便B可以从中访问A,反之亦然。我不明白这怎么可能扩展到超过少量互连的指针。

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

于 2012-11-29T08:19:49.187 回答