2012-07-07 15 views
12

He estado agregando visualizadores para algunos de nuestros tipos a autoexp.dat. Incluso con that blog that everyone refers back (¡incluso los chicos de Microsoft!) A veces ha sido difícil.Visualización de árboles en VS2008

Pero estoy completamente perplejo con el visualizador #tree. En primer lugar, la publicación del blog parece estar llena de agujeros en su descripción (y ningún otro material que he podido encontrar aborda eso, pero otros claramente lo han puesto en práctica). En particular, parece haber algunos casos mágicos en los que sabe desreferenciar un puntero, pero no puedo estar seguro de haber modificado la intención. También parece haber cierta ambigüedad entre cuando usa $ c y $ e. AFAICS parecen ser intercambiables, ¿quizás se permiten ambos como ayuda para la legibilidad? ¿O realmente significan cosas diferentes (ese blog, por ejemplo, usa $ e donde los visualizadores STL que vienen con VS2008 usan $ c).

Pero lo que realmente falta es una explicación de cómo encaja todo. Me hubiera imaginado que sería seguir este proceso:

  1. aplicar la regla de "cabeza" para llegar al nodo de partida (por puntero)
  2. aplicar la regla DEREF (el bit al final) a la dereferenced nodo actual para obtener el valor de visualización.
  3. Aplicar las reglas izquierda y derecha al desreferenciado nodo actual para llegar a los nodos izquierdo y derecho, respectivamente (por puntero - con nulo como terminador, a menos que se especifique una regla de omisión).
  4. Vaya a (2) hasta que se hayan visitado todos los nodos.

Obviamente hay un algoritmo para navegar hacia la izquierda/derecha que he pasado por alto. Eso no es muy importante. Lo que es más importante es qué valores se consideran en cada etapa y cuándo ocurre la desreferenciación.

Ese parece ser el único proceso que puedo imaginar que se ajusta a los ejemplos que he visto. Pero no he podido lograr que funcione con nuestra implementación de árbol. Acabo de obtener (error) donde deberían mostrarse los #tree hijos (obtengo uno (error) para cada nodo, así que supongo que el tamaño se está capturando correctamente). ¡He intentado alguna variación posible en la que pueda pensar, la mayoría varias veces!

La otra cosa que me desconcierta es que muchos ejemplos que he visto, incluidos los paquetes stl, navegan de cabeza a padre (o similar), y omiten el nodo principal. ¿Por qué hacen eso?

Aquí está el visualizador que estoy usando (en una de las formas que he probado - y los nombres han sido cambiados para proteger la ... corporativa):

MyTree<*,*,*>{ 
    children(
     #(
      [raw members]: [$c,!], 
      #tree 
      (
       head : $c.m_root.m_p, 
       size : $c.m_size, 
       left : left.m_p, 
       right : right.m_p 
      ) : $e.value 
     ) 
    ) 
} 

Y aquí algo de pseudo-código para mis clases de árboles:

MyTree: 
    Ptr<Note> m_root 
    int m_size 

Node: 
    ValueT value 
    Ptr<Node> left 
    Ptr<Node> right 

... donde Ptr <> es un puntero inteligente, manteniendo el puntero del crudo en m_p.

Cualquier ayuda sería muy apreciada.

+0

Parte de esto podría funcionar solo para los diseños de MS que se probaron. Como los que tienen un nodo centinela (que pueden omitir). He tenido problemas similares al intentar encajar en un diseño de lista vinculado que se desvía del original. No hay suerte con eso. –

+0

No tengo un nodo centinela, por lo que debería ser * más fácil *, habría pensado. El mío se parece más al ejemplo de virtualdub en muchos aspectos, la mayor diferencia es mi uso de punteros inteligentes. – philsquared

Respuesta

5

Empezamos realmente realmente necesitando esto! Así que abrí una recompensa pero seguí mirándolo.

¡Parece que lo he resuelto! (para mi caso).En realidad estaba muy cerca:

MyTree<*,*,*>{ 
    children(
     #(
      [raw members]: [$c,!], 
      #tree 
      (
       head : $c.m_root.m_p, 
       size : $c.m_size, 
       left : left, 
       right : right 
      ) : $e.value 
     ) 
    ) 
} 

El truco es que la regla cabeza necesita para especificar completamente cómo llegar al puntero prima dentro del puntero inteligente, pero las reglas/Derecha e Izquierda no lo hacen (y tampoco lo hace la de- Regla del árbitro).