In the code below, there is a Grid
which contains points
. Likewise, Element
and Face
also have points
but I want to them to point to points
in Grid
.
Should I use smart or raw pointers. If I use smart pointers should I use std::unique_ptr
or std::shared_ptr
?
struct Vector3
{
vector <double> dim;
Vector3 ()
{
dim.resize(3);
}
};
struct Element
{
vector <Vector3*> points;
};
struct Face
{
vector <Vector3*> points;
};
struct Grid
{
vector <Vector3> points;
vector <Element> elms;
vector <Face> faces;
};
Here you specified that the precondition is that Element
and Face
objects are created in a Grid
object with the elements of the container referring to the same Grid
containers, therefore the lifetime of all three containers (points
, elms
and faces
) is the same.
Now you have to consider two cases.
Semi-immutable points
In this case, points
is guaranteed to never invalidate references to its elements (eg. it's never modified). Here you don't need any smart pointers, you can just use a simple std::reference_wrapper
as follows:
struct Vector3
{
std::vector<double> dim;
Vector3 () : dim(3) {}
};
template<class Type>
using ref_vec = std::vector<std::reference_wrapper<Type>>;
struct Element { ref_vec<Vector3> points; };
struct Face { ref_vec<Vector3> points; };
struct Grid
{
std::vector<Vector3> points;
std::vector<Element> elms;
std::vector<Face> faces;
};
Another solution, non equivalent to your example (elms
and faces
don't have direct access to the Vector3
object) might be to use indexes:
struct Vector3
{
std::vector<double> dim;
Vector3 () : dim(3) {}
};
struct Grid
{
struct Element { std::size_t point_indices; };
struct Face { std::size_t point_indices; };
std::vector<Vector3> points;
std::vector<Element> elms;
std::vector<Face> faces;
};
That is, you store the indices of points
.
Mutable points
If the operations performed on points
can invalidate references, then you might want to consider another container that does not invalidate references/pointers/iterators to the element.
For example std::deque
guarantees the validity of references for deletion/insertion at the beginning and end of the container.
Once you have chosen the correct container you can just apply the same ideas as above.