使用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
答案 0 :(得分:2)
这是一个简单的测试。在17个顶点上创建一个完整的图形,这样程序只指向顶点0.开始随机删除边。你的想法有用吗? (剧透:它没有)。
答案 1 :(得分:1)
我会想象你可以沿着这些方向做某事。但是,在这样的结构中,每个指针A
都需要知道每个其他指针B
,这样B
可以从A
到达,反之亦然。我没有看到它如何可以扩展到更多的互连指针。
似乎如果你想在没有程序员帮助的情况下支持循环引用,你或多或少需要一个完整的垃圾收集器而不是简单的引用计数方案(我很想在这方面被证明是错误的)。