Умные указатели или «лучший» деструктор - PullRequest
2 голосов
/ 01 сентября 2010

Какой тип интеллектуального указателя (общий, объемный) будет для таких структур данных наиболее подходящим ...

Структура 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;}
    ...

};

Структура 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;
...
};

Я бы хотел сохранить Edges и PointTopo, используя 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();
        }

}

Но есть проблемы с деструктором, поэтому я подумал, стоит ли использовать подсчет ссылок.

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
}

Точки p1, p2 будут сохранены в обоих списках, tl1, tl2. Деструктор tl2 вызывает исключение, точки p1 и p2 уже были удалены с использованием деструктора tl1.

Этот пример не является синтетическим. Представьте, что nl2 представляет собой подмножество nl1, например, выпуклую оболочку nl1 ...

Я думаю, что эту проблему нельзя решить без подсчета ссылок ... Поэтому я пытаюсь использовать какой-нибудь умный указатель ...

Большое спасибо за помощь ...

Ответы [ 3 ]

2 голосов
/ 01 сентября 2010

Деструктор tl2 вызывает исключение, точки p1 и p2 уже были удалены с использованием деструктора tl1.

Вы пытаетесь delete объект p1p2) дважды.Это вызывает UB - плохая вещь, чтобы сделать.Попробуйте shared_ptr (умные указатели с подсчетом ссылок), которые доступны как в std::tr1 пространстве имен (см. Документацию вашего компилятора для получения дополнительной информации), так и в Boost.

Другая вещь, которую нужно сделать, - это скопировать объекты (а неуказатели, как вы делаете сейчас).И это потребовало дублирования PointTopo объектов.

(Лично я был бы склонен использовать unique_ptr для членов Edge и PointTopo в изоляции.)

2 голосов
/ 01 сентября 2010

shared_ptr<> выполняет подсчет ссылок и управление несколькими указателями на один и тот же объект, удаляя объект при уничтожении последнего указателя на него.

scoped_ptr<> делает указатель вести себя как переменная стекаудаляет указанный объект, как только указатель выходит из области видимости.Это не то поведение, которое вы ищете здесь.

В вашем случае использования подсчет ссылок, предоставленный shared_ptr<>, - это то, что вам нужно.

1 голос
/ 01 сентября 2010

что вам нужно, это повышение :: shared_ptr

...