简体   繁体   English

智能指针或“更好”的析构函数

[英]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: 结构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: 结构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: 我想使用向量存储Edges和PointTopo:

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. 点p1,p2将存储在两个列表tl1,tl2中。 Destructor of tl2 causes an exception, points p1 and p2 has already been deleted using tl1 destructor. tl2的析构函数导致异常,点p1和p2已使用tl1析构函数删除。

This example is not synthetic. 这个例子不是合成的。 Imagine, that nl2 represents subset of nl1, for example the convex hull of nl1... 想象一下,nl2代表nl1的子集,例如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. tl2的析构函数导致异常,点p1和p2已使用tl1析构函数删除。

You are trying to delete the object p1 (and p2 ) twice. 您试图两次delete对象p1 (和p2 )。 That invokes UB -- a Bad Thing to do. 这调用了UB-做一件坏事。 Try shared_ptr (reference counted smart pointers) which is available both in std::tr1 namespace (see your compiler documentation for further details) or Boost. 尝试在std::tr1命名空间(请参阅编译器文档以获取更多详细信息)或Boost中都可用的shared_ptr (引用计数的智能指针)。

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. PointTopo需要复制PointTopo对象。

(Personally, I'd be inclined to use unique_ptr for members of Edge and PointTopo in isolation.) (就我个人而言,我倾向于对EdgePointTopo成员单独使用unique_ptr 。)

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. shared_ptr<>会引用计数和管理指向同一对象的多个指针,并在销毁指向该对象的最后一个指针时删除该对象。

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. scoped_ptr<>使指针的行为类似于堆栈变量,一旦指针超出范围,它将删除指向的对象。 This not the behavior you are looking for here. 这不是您在此处寻找的行为。

In your use case the reference counting provided by shared_ptr<> is what you want. 在您的用例中, shared_ptr<>提供的引用计数就是您想要的。

您需要的是boost :: shared_ptr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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