Implications of modeling ownership using smart pointers
<p>I am currently manually managing the lifecycle of objects in my project. I am considering switching to smart pointers, specifically tr1::shared_pointer and tr1::weak_ptr. However, I am seeing a couple of problems and would like to get some input on best practices.</p>

<p>Consider the following class diagram:</p>

<p><img src="http://i.stack.imgur.com/TDGcb.jpg" alt="Polyhedron Class Diagram"></p>

<p>In this diagram, the thick arrows represent associations with an ownership semantics (the source is responsible for deleting the target or targets). The thin arrows represent associations without ownership.</p>

<p>From what I understand, one way of implementing an association with ownership semantics would be to use tr1::shared_ptr (or a collection thereof). Other associations can be implemented using either tr1::shared_ptr or tr1::weak_ptr. The former is prohibited if it may result in circular references because that would prevent proper release of resources.</p>

<p>As you can see, there is a circle of associations between classes Edge and Side. I can easily break this by implementing the "left" and "right" associations from Edge to Side using tr1::weak_ptrs. However, I would prefer using the smart pointers to document, in code, the ownership semantics of the associations. So I would like to use shared_ptrs only for the associations represented by thick arrows in the diagram, and weak_ptrs for everything else.</p>

<p>Now my first question is: Should I use weak_ptrs liberally as described above, or should I use them as little as possible (only to avoid circular references)?</p>

<p>The next question is: Suppose I have a function that computes the average of a set of vertices. Suppose further that I have implemented the association from the Polyhedron to its Vertices like so: </p>

<pre><code>class Vertex;
class Polyhedron {
protected:
    std::vector&lt;std::tr1::shared_ptr&lt;Vertex&gt; &gt; m_vertices;
};
</code></pre>

<p>and that I have implemented the association from a Side to its Vertices like so:</p>

<pre><code>class Vertex;
class Side {
protected:
    std::vector&lt;std::tr1::weak_ptr&lt;Vertex&gt; &gt; m_vertices;
};
</code></pre>

<p>Note that the set of vertices of a Side is a subset of the set of vertices of a Polyhedron. Now let's say I have a function that computes the average of a set of vertices. The function is currently declared like so:</p>

<pre><code>const Vertex centerOfVertices(std::vector&lt;Vertex*&gt; vertices);
</code></pre>

<p>Now if I represent the associations as above, I suddenly need two functions if I understand everything correctly:</p>

<pre><code>const Vertex centerOfVertices(std::vector&lt;std::tr1::shared_ptr&lt;Vertex&gt; &gt; vertices);
const Vertex centerOfVertices(std::vector&lt;std::tr1::weak_ptr&lt;Vertex&gt; &gt; vertices);
</code></pre>

<p>Because I cannot convert between a vector of shared_ptr and a vector of weak_ptr. This smells funny to me. I would like to know what approach I should take here to avoid such a situation.</p>
