2015-04-23 2 views
0

У меня есть объект графа, и я хотел бы создать деструктор для этого. Тем не менее, я не очень комфортно с рекурсивностью, и я немного потерял свои собственные структуры данных. Я покажу участвующие классы и мое начало деструктора.Деструктор, граф и рекурсия

class Graph { 

private : 
     Graph*    parent; 
     vector<Graph>  child; 
     Board    tab; 
     bool     seen; 

public : 
     Graph(const Board&); 
     Graph(const Board&, Graph*); 
     ~Graph(); 
     ... 
}; 

class Board {   
    private : 
     int**   tab; 
     int    nbline; 
     int    nbcolumn; 
     Position  emptyspot; 

    public : 
     Board(); 
     Board(int, int, Play&); 
     Board(int, int); 
     Board(const Board&); 
     Board(int, int, ifstream&); 
     ~Board(); 
     ... 
}; 

Класс позиции получил только 2 int (строка и столбцы). Совета деструкторов работы:

Board::~Board() 
{ 
    for(int i = 0; i < this->nbline; i++) { 
     delete tab[i]; 
    } 
    delete tab; 
} 

Как вы уже догадались, я хотел бы, чтобы уничтожить узел моего графа, и все последующие узлы.

Вот мой beggining:

Graph::~Graph() {   
    while(!child.empty()) {     
     for(vector<Graph>::iterator itr = child.begin; itr != child.end; ++itr) { 
      delete child[itr]; 
     } 
    } 
} 

Таким образом, я иду в все мои ветви, рекурсивно, правильно? Когда я нахожу лист (вектор равен нулю) - если уничтожить все, что произойдет в векторе родителя?

Я не знаю, будет ли родитель установлен в NULL (я так не думаю), а пространство памяти родительского вектора не будет нераспределенным, поэтому условие child.empty() не будет выполнено, правильно ?

  • Как и когда я разрушаю диаграмму *?

  • Я могу рискнуть переполнением стека?

    • Могу ли я назвать vector.erase() в корневом узле, где я начинаю удалять, чтобы уничтожить все рекурсивно вместо того, чтобы делать для цикла?
+0

является дочерним элементом или вектором ? У вас есть 'vector ', но вы вызываете delete, поэтому я запутался. – NathanOliver

+0

Это моя ошибка, это должен быть вектор , мне тоже придется менять конструкторы ^^ ' – Csi

ответ

2

Ваш деструктор неверен по многим причинам.

  1. Ваш child член должен, вероятно, будет vector<Graph*>, так что вы можете на самом деле delete их.
  2. Ваша петля бесконечна, если у вашего Graph есть дети, так как вы никогда не меняете размерchild вектор.
  3. child[itr] не так, как вы получаете Graph*, соответствующий итератору, *itr есть.
  4. begin и end являются функциями-членами, поэтому их нужно называть.
  5. Члену, вероятно, следует называть children, нет?

Правильный цикл будет:

for (vector<Graph*>::iterator itr = children.begin(); itr != children.end(); ++itr) { 
    delete *itr; // this will recursively call Graph::~Graph() 
       // on the children, and then free their memory 
} 

Или, в C++ 11, мы просто определяем:

std::vector<std::unique_ptr<Graph>> children; 

Так что очистка памяти будет обрабатываться для нас.

+0

@Csi: Если у вас нет возможностей C++ 11, установите флажок [Boost Smart Pointers] (http://www.boost.org/doc/libs/release/libs/smart_ptr/smart_ptr.htm). Это то же самое, в основном, реализовано с использованием средств C++ 98. – DevSolar

+0

@DevSolar Я не имею права использовать Boost; _; Учитель - очень старая школа: '( – Csi

+0

@DevSolar Thx buddy :-) Я ответил на эту тему с изменениями после консультаций с людьми, правильно ли сейчас? – Csi