没有使用shared_ptr<>
的经验我想知道以下是否是一个合适的用例,以及将shared_ptr<>
返回给用户是否是一个好主意。
我有一个结构图,节点之间有多个连接。在遍历图形期间,为每个节点分配一个值(从连接的节点计算),并且我希望用户能够轻松地访问该值。整个事情看起来(强烈简化)像这样:
class Pool;
class Node {
public:
typedef std::tr1::shared_ptr<Node> Ptr;
...
void compute_dependencies() {
...
// calls Pool to get a new Node instance
dependencies_.push_back(Pool::create_node(...));
...
}
// evaluate the current node
void evaluate() { /* use dependencies_ */ };
double value() const { if(evaluated) return value_; };
private:
std::vector<Node::Ptr> dependencies_; // vector<Node*> better?
dbl value_;
}
// Pool creates and owns all nodes
class Pool {
public:
static const Node::Ptr create_node(...); // create a new node
void traverse_and_evaluate();
private:
std::vector<Node::Ptr> allnodes; // appropriately sorted to ensure
// dependencies are evaluated
...
}
并且用户致电:
Pool pool();
Node::Ptr node1 = Pool::create_node(...);
Node::Ptr node2 = Pool::create_node(...);
....
pool.traverse_and_evaluate();
// ready to read out the now populated values
cout << node1->value() << " " << node2->value() << ...
这样做的好处是用户可以直接访问他关心的节点(依赖性通常是无趣的)。但我不能100%肯定这是不是一个好主意。
感谢您的投入!
编辑:没有循环依赖。
答案 0 :(得分:10)
shared_ptr
主要用于对象没有明确的所有者(或者可能需要比其拥有者更长)的时候,所以没有明显的地方可以摧毁它。 shared_ptr
基本上成为所有者,当对象的最后shared_ptr
超出范围时,对象将被销毁。
如果您有一个明确的所有者,例如Pool
课程,并且Node
对象不需要比拥有Pool
更长,那么实际上并不多需要一个shared_ptr
。你可以破坏所有者析构函数中的对象。
答案 1 :(得分:3)
我喜欢通过weak_ptr提供对其他人的访问,你可以构造一个weak_ptr&lt;节点&gt;直接来自shared_ptr&lt;节点&gt;。
用户通常会从池中检索weak_ptr,然后构建一个shared_ptr&lt;节点&gt;来自weak_ptr&lt;节点&gt; .lock()。
这向用户传达了他们没有所有权的权利,并且应该注意不要将锁保持的时间超过必要的时间 - 或者至少对我来说是这样:)