正确使用shared_ptr

Appropriate use of shared_ptr?

本文关键字:ptr shared      更新时间:2023-10-16

没有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() << ... 

这样做的好处是用户可以直接访问他关心的节点(依赖关系通常是无趣的)。但我不能百分之百确定这是不是一个好主意。

感谢您的输入!

编辑:没有循环依赖

shared_ptr主要用于对象没有明确的所有者(或者可能需要比其所有者更长寿)的时候,因此没有明显的地方可以销毁它。shared_ptr实质上成为了所有者,当最后一个shared_ptr超出作用域时,对象将被销毁。

当你有一个明确的所有者时,比如你的Pool类,并且不需要Node对象比拥有Pool的对象活得长,那么真的不太需要shared_ptr

我喜欢通过weak_ptr提供对其他人的访问,您可以构造一个weak_ptr<直接从shared_ptr><节点> .

用户通常会从池中检索一个weak_ptr,然后构造一个shared_ptr from weak_ptr<节点> .lock () .

这向用户传达了他们没有所有权的信息,并且应该小心不要维护锁的时间超过必要的时间——或者至少对我来说是这样的:)