C++ 使用智能指针建模所有权的含义
我目前正在手动管理项目中对象的生命周期。我正在考虑切换到智能指针,特别是tr1::shared_pointer和tr1::weak_ptr。然而,我发现了一些问题,希望获得一些关于最佳实践的信息 考虑以下类图: 在此图中,粗箭头表示与所有权语义的关联(源负责删除一个或多个目标)。细箭头表示没有所有权的关联 据我所知,实现所有权语义关联的一种方法是使用tr1::shared_ptr(或其集合)。其他关联可以使用tr1::shared_ptr或tr1::weak_ptr实现。如果前者可能导致循环引用,则禁止前者,因为这将妨碍资源的适当释放 正如您所看到的,在类Edge和Side之间有一个关联圈。我可以通过使用tr1::weak_ptrs从边到边实现“左”和“右”关联来轻松打破这种局面。然而,我更喜欢使用智能指针在代码中记录关联的所有权语义。因此,我只想对图中由粗箭头表示的关联使用shared_ptr,对其他所有关联使用弱_ptr 现在我的第一个问题是:我应该像上面描述的那样自由地使用弱ptr,还是应该尽可能少地使用它们(只是为了避免循环引用) 下一个问题是:假设我有一个计算一组顶点平均值的函数。进一步假设我实现了从多面体到其顶点的关联,如下所示:C++ 使用智能指针建模所有权的含义,c++,C++,我目前正在手动管理项目中对象的生命周期。我正在考虑切换到智能指针,特别是tr1::shared_pointer和tr1::weak_ptr。然而,我发现了一些问题,希望获得一些关于最佳实践的信息 考虑以下类图: 在此图中,粗箭头表示与所有权语义的关联(源负责删除一个或多个目标)。细箭头表示没有所有权的关联 据我所知,实现所有权语义关联的一种方法是使用tr1::shared_ptr(或其集合)。其他关联可以使用tr1::shared_ptr或tr1::weak_ptr实现。如果前者可能导致循环引
class Vertex;
class Polyhedron {
protected:
std::vector<std::tr1::shared_ptr<Vertex> > m_vertices;
};
类顶点;
类多面体{
受保护的:
std::向量m_顶点;
};
我已经实现了从侧面到顶点的关联,如下所示:
class Vertex;
class Side {
protected:
std::vector<std::tr1::weak_ptr<Vertex> > m_vertices;
};
类顶点;
班边{
受保护的:
std::向量m_顶点;
};
请注意,边的顶点集是多面体顶点集的子集。现在让我们假设我有一个函数,计算一组顶点的平均值。函数当前声明如下:
const Vertex centerOfVertices(std::vector<Vertex*> vertices);
const顶点中心顶点(std::向量顶点);
现在,如果我像上面那样表示关联,如果我正确理解了所有内容,我突然需要两个函数:
const Vertex centerOfVertices(std::vector<std::tr1::shared_ptr<Vertex> > vertices);
const Vertex centerOfVertices(std::vector<std::tr1::weak_ptr<Vertex> > vertices);
const顶点中心顶点(std::向量顶点);
顶点的常数顶点中心(标准::向量顶点);
因为我不能在共享的向量和弱的向量之间转换。这闻起来很怪。我想知道我应该采取什么方法来避免这种情况
然而,我更喜欢使用智能指针在代码中记录关联的所有权语义
这是你应该做的。毕竟,这是他们完美表达的
因此,我只想对图中由粗箭头表示的关联使用shared_ptr,对其他所有关联使用弱_ptr
去做吧,但有一点需要注意:你的所有权根本不像共享所有权,它是简单、独特的所有权。因此,这里合适的智能指针不是shared_ptr
,而是std::unique_ptr
,而弱指针将只是原始指针
现在如果我像上面那样表示关联,我突然需要两个函数
对。或者你使用模板
或者,由于函数实际上对共享所有权根本不感兴趣,您可以将原始指针传递给它,但这当然意味着首先从结构中获取原始指针,这需要为客户端添加一个步骤,这可能对接口不好。您当然也可以将共享的ptr用于循环引用。在一些罕见的情况下,这是有意义的。但是,一旦处理完对象,就必须小心打破循环。使用共享指针似乎是明智的,特别是当您发现顶点等可以在多面体之间共享时 要将弱指针向量转换为共享指针向量,请使用显式构造函数:
centerOfVertices(std::vector<std::tr1::shared_ptr<Vertex> >(vertices.begin(), vertices.end()));
顶点中心(std::vector(顶点.begin(),顶点.end());
什么意思“弱ptr不能转换为共享ptr”?在
weak_ptr
上调用lock()
,它会给你一个shared
我认为这会滥用shared_ptr
,我没有仔细阅读,但它看起来并不是什么真正的共享所有权。使用unique\u ptr
和原始指针,并保证您为系统提供(弱)原始指针,它们指向的对象在其作用域内有效。我想如果我知道方面
代表什么,我会更好地理解这一点。它是指“脸”吗?@johndilling谢谢你指出这一点,我不知道。戴夫:那里没有一个主要实体对“所有者”或“家长”有严格的定义。在多面体相交的地方,它们可以共享顶点、边和顶点,或者边、顶点和面。我想这就是OP想要表现的。