【发布时间】:2012-11-29 06:01:06
【问题描述】:
使用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中是否已经存在这样的想法?- 如果不是,是不是因为这是一个糟糕的主意?(或者我只是想出了一些聪明的办法?)
【问题讨论】:
-
我无法想象需要通过一些小改动来轻松避免这种需求。我认为主要问题是有时(或经常)您可能不希望同时创建指针,这可能会使它变得更加复杂。或者强迫程序员显式链接指针只是自找麻烦。请注意,您的 shared_count_ptr 类可能不应该有 shared_ptr 成员,因为它已经继承了它,除非我误解了您的设计。
-
继承是从 is-a 遗留下来的,并且将转到 has-a。固定的。我敢肯定有更好的方法来实现这一点,而且不会那么难看。
-
我猜如果你的算法使用链表而不是简单的共享 int 计数器,你可以检测循环。
标签: c++ boost smart-pointers raii reference-counting