简体   繁体   中英

Smart pointers, or “better” destructor

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...

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.)

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.

您需要的是boost :: shared_ptr

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM