Es un destructor recursivo para la lista vinculada, el árbol, etc., malo?

Para mi ejercicio de aprendizaje actual, estoy estudiando listas y árboles vinculados. Hace poco vi una sugerencia para destruir estructuras de datos de forma recursiva haciendo que cada nodo elimine su hijo / hijos. Sin embargo, en casi todos los ejemplos que he encontrado, el destructor de nodos está vacío y algunas clases de gestión manejan la destrucción mediante alguna forma de iteración y eliminación. Desde una perspectiva de confiabilidad y / o estilística, ¿hay algo inherentemente malo en el destructor recursivo?

o que sigue es mi implementación de mi comprensión de los dos enfoque

Destrucción recursiva:

#include <iostream>
struct Node {
  static int count;
  Node() : num_(count++), p_next_(0) {}
  ~Node() { 
    std::cout << "entering " << num_ << "\n";
    delete p_next_;
    std::cout << " leaving " << num_ << "\n";
  }
  const int num_;
  Node* p_next_;
};
int Node::count = 0;
int main () {
  Node* p_head = new Node();
  p_head->p_next_ = new Node();
  p_head->p_next_->p_next_ = new Node();
  delete p_head;
  return 0;
}

Y aquí está mi opinión sobre la destrucción de manejo de la clase de gestión. Suponiendo que haya definido el siguiente DTOR para Node:

~Node() {std::cout << "Someone deleted " << num_ << "\n";}

Definiría la siguiente clase de gestión LinkedList y la siguiente

/* other stuff from above */
class LinkedList {
public:
  LinkedList() : p_head_(new Node()) {
    p_head_->p_next_ = new Node();
    p_head_->p_next_->p_next_ = new Node();
  }
  ~LinkedList() {
    while(Node* p_prev = p_head_) {
      p_head_ = p_head_->p_next_;
      delete p_prev;
    }
  }
private:
  Node* p_head_;
};
int main () {
  LinkedList* p_list = new LinkedList();
  delete p_list;
  return 0;
}

uponiendo que estoy leyendo mis resultados correctamente, mis dos implementaciones hacen lo mismo.

Con respecto a mi ejemplo de destrucción recursiva, creo que casi siempre necesitaré algún tipo de clase de gestión que contenga una copia de cabeza cuando resuelva un problema real con el código, pero la clase de gestión solo necesita eliminar el nodo de cabeza / raíz para garantizar la destrucción de toda la estructura de datos. Me parece más elegante, pero me he metido en problemas con el código que pensé que estaba bien.

¿Debería la clase de gestión ser la responsable de asegurarse de que todo se elimine correctamente? ¿O es mejor que la estructura de datos subyacente sepa cómo limpiarse? ¿Hay alguna trampa que no sea obvia?

¡Gracias

--Jordá

edit: Se me ocurrió una idea. Si tengo una cadena de nodos atrozmente larga, ¿tengo que preocuparme por un desbordamiento de pila durante la destrucción en el primer ejemplo ya que la recursión está en juego?

edit2: supongo que debería haber sido obvio. Y ahora me siento un poco tonto. En mi máquina, si tengo más de 64910 nodos, me caigo. Entonces, la recursión presenta claramente una trampa.

Respuestas a la pregunta(2)

Su respuesta a la pregunta