Reputation: 637
Which type of the smart pointer (shared, scoped) would be for such a data structures the most suitable...
Structure 1:
//Class with cross-references to points p1, p2
class PointTopo
{
private:
double x, y;
PointTopo * p1;
PointTopo * p2;
public:
PointTopo(double xx, double yy): x(xx), y(yy) {this-> p1 = NULL; this->p2 = NULL;}
...
};
Structure 2:
//Class with cross references: topological model for Delaunay triangulation
class Edge
{
private:
Point * start; //Only 2D point without topo information
Edge *next;
Edge *previous;
Edge *twin;
...
};
I would like to store Edges and PointTopo using vector:
class PointsTopoList
{
private:
std::vector <PointTopo *> points;
public:
inline void push_back ( PointTopo *p ) { points.push_back ( p );}
~PointsTopoList() {clear();}
void clear()
{
for ( TNodes2DList::iterator i_points= points.begin(); i_points!= points.end(); ++i_points)
{
if ( *i_points!= NULL )
{
delete *i_points;
*i_points= NULL;
}
points.clear();
}
}
But there are problems with destructor, so I wondered whether or not to use reference counting.
int main()
{
PointTopo *p1 = new PointTopo(0,0);
PointTopo *p2 = new PointTopo(10,10);
PointTopo *p3 = new PointTopo(20,20);
PointTopo *p4 = new PointTopo(30,30);
PointsTopoList tl1;
tl1.push_back(p1);
tl1.push_back(p2);
tl1.push_back(p3);
tl1.push_back(p4);
PointsTopoList tl2;
tl2.push_back(p1); //P1 is stored in tl1 and tl2
tl2.push_back(p2); //P2 is stored in tl1 and tl2
}
Points p1, p2 will be stored in both list, tl1, tl2. Destructor of tl2 causes an exception, points p1 and p2 has already been deleted using tl1 destructor.
This example is not synthetic. Imagine, that nl2 represents subset of nl1, for example the convex hull of nl1...
I think, that this problem could not be solved without refererence counting... So I try to use some smart pointer...
Thank you very much for your help...
Upvotes: 2
Views: 983
Reputation: 229754
shared_ptr<>
does reference counting and management of several pointers to the same object, deleting the object when the last pointer to it is destroyed.
scoped_ptr<>
makes a pointer behave like a stack variable, it deletes the pointed-to object as soon as the pointer goes out of scope. This not the behavior you are looking for here.
In your use case the reference counting provided by shared_ptr<>
is what you want.
Upvotes: 2
Reputation: 111240
Destructor of tl2 causes an exception, points p1 and p2 has already been deleted using tl1 destructor.
You are trying to delete
the object p1
(and p2
) twice. That invokes UB -- a Bad Thing to do. Try shared_ptr
(reference counted smart pointers) which is available both in std::tr1
namespace (see your compiler documentation for further details) or Boost.
The other thing to do is to copy the objects (and not the pointers as you are doing now). And that'd required duplicating PointTopo
objects.
(Personally, I'd be inclined to use unique_ptr
for members of Edge
and PointTopo
in isolation.)
Upvotes: 2