C++ 是否正确使用共享ptr?

C++ 是否正确使用共享ptr?,c++,shared-ptr,ownership,C++,Shared Ptr,Ownership,由于没有使用shared\u ptr的经验,我想知道下面的用例是否合适,以及将shared\u ptr返回给用户是否是一个好主意 我有一个类似于图的结构,节点之间有多个连接。在遍历图的过程中,每个节点都被分配一个值(从连接的节点计算),我希望用户能够轻松地访问该值。整个过程看起来(非常简化)如下: class Pool; class Node { public: typedef std::tr1::shared_ptr<Node> Ptr;

由于没有使用
shared\u ptr
的经验,我想知道下面的用例是否合适,以及将
shared\u 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 
        ...
}
类池;
类节点{
公众:
typedef std::tr1::shared_ptr ptr;
...
void compute_dependencies(){
...
//调用池以获取新节点实例
依赖项。向后推(池::创建节点(…);
...
}
//计算当前节点的值
void evaluate(){/*使用依赖项*/};
double value()常量{if(求值)返回值};
私人:
std::vector dependencies_;//vector更好吗?
dbl值;
}
//池创建并拥有所有节点
班级池{
公众:
静态常量节点::Ptr create_Node(…);//创建一个新节点
无效遍历_和_求值();
私人:
std::vector allnodes;//适当排序以确保
//对依赖项进行评估
...
}
并且用户调用:

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() << ... 
Pool();
Node::Ptr node1=Pool::create_节点(…);
Node::Ptr node2=Pool::create_节点(…);
....
pool.transverse_和_evaluate();
//准备好读取现在填充的值了吗

cout value()我喜欢通过弱ptr提供对他人的访问,您可以直接从共享的弱ptr构建弱ptr

用户通常会从池中检索弱\u ptr,然后从弱\u ptr.lock()构建共享的\u ptr


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

共享\u ptr
主要用于对象没有明确的所有者(或者可能需要比其所有者长寿)的时候,所以没有明显的地方可以摧毁它。
shared_ptr
实质上成为所有者,当对象的最后一个
shared_ptr
超出范围时,该对象将被销毁


当你有了一个明确的所有者,比如你的
类,并且
节点
对象不需要比拥有的
更久,那么就真的不需要
共享的ptr
。您可以只销毁所有者析构函数中的对象。

您可能会发现这个问题和答案有一定的相关性:谢谢,这使它更加清晰。因此,您的意思是
create_node()
应该返回一个原始指针,该指针存储在
向量allnodes
中?复制不是一个选项,因为
节点
在创建时没有计算。@bbtrb:返回
节点*
是可以的,但我建议使用
std::vector
(无泄漏)。如果确实无法复制
节点
(如果它是基类),则可以使用
boost::ptr_vector
@bbtrb:yes,返回原始指针就足够了。