我目前手动管理项目中对象的生命周期。我正在考虑切换到智能指针,特别是tr1::shared_pointer和tr1::weak_ptr。然而,我遇到了一些问题,希望得到一些最佳实践的建议。
考虑以下类图:
在这个图中,粗箭头表示具有所有权语义的关联(源负责删除目标或目标)。细箭头表示没有所有权的关联。
据我所知,实现具有所有权语义的关联的一种方法是使用tr1::shared_ptr(或其集合)。其他关联可以使用tr1::shared_ptr或tr1::weak_ptr来实现。如果可能导致循环引用,则不能使用前者,因为那会防止正确释放资源。
正如您所看到的,Edge和Side类之间存在一圈关联。我可以轻松地通过使用tr1::weak_ptrs从Edge到Side实现“left”和“right”关联来打破这个圈子。但是,我更喜欢使用智能指针来记录代码中关联的所有权语义。因此,我只想在图中由粗箭头表示的关联中使用shared_ptrs,并在其他所有情况下使用weak_ptrs。
现在我的第一个问题是:我应该像上面描述的那样慷慨地使用weak_ptrs,还是尽可能少地使用它们(仅避免循环引用)?
下一个问题是:假设我有一个计算一组顶点平均值的函数。进一步假设我已经实现了从Polyhedron到其顶点的关联,如下所示:
class Vertex;
class Polyhedron {
protected:
std::vector<std::tr1::shared_ptr<Vertex> > m_vertices;
};
我已经实现了从一个侧面到其顶点的关联,方法如下:
class Vertex;
class Side {
protected:
std::vector<std::tr1::weak_ptr<Vertex> > m_vertices;
};
注意,面的顶点集是多面体顶点集的子集。现在假设我有一个计算一组顶点平均值的函数。该函数当前声明如下:
const Vertex centerOfVertices(std::vector<Vertex*> vertices);
现在,如果我按照上述方式表示关联,如果我理解正确的话,我需要两个函数:
const Vertex centerOfVertices(std::vector<std::tr1::shared_ptr<Vertex> > vertices);
const Vertex centerOfVertices(std::vector<std::tr1::weak_ptr<Vertex> > vertices);
我无法将shared_ptr的向量转换为weak_ptr的向量,这让我感到有些奇怪。我想知道在这种情况下应该采取什么方法来避免这种情况。
shared_ptr
,我没有仔细阅读,但似乎没有任何东西实际上共享所有权。相反,请使用unique_ptr
和原始指针,并向您提供(弱)原始指针的系统保证指向的对象在其范围内将有效。 - Davidside
代表什么,我会更好地理解这个的。它是指 '面' 吗? - Rook