2015-01-18 13 views
5

In Stroustrup linguaggio di programmazione C++ (4 ° ed), la sezione 27.4.2 mostra una tecnica per "linearizzare" una gerarchia di classi di diamante per evitare il sovraccarico delle classi di base virtuali. Si inizia con il modello di diamante da un vero e proprio progetto (Pivot code analyzer tool):Explanation of Stroustrup Linearizing Class Hierarchies example

enter image description here

La versione lineare è disegnato come:

enter image description here

e

enter image description here

Il schema del codice è:

namespace ipr { 
    struct Node { ... }; 
    struct Expr : Node { ... }; 
    struct Stmt : Expr { ... }; 
    struct Decl : Stmt { ... }; 
    struct Var : Decl { ... }; 

    namespace impl { 
     template<class T> struct Node : T { ... }; 
     template<class T> struct Expr : Node<T> { ... }; 
     template<class S> struct Stmt : S { ... }; 
     template<class D> struct Decl : Stmt<Expr<D>> { ... }; 
     struct Var : Decl<ipr::Var> { ... }; 
    } 
} 

Sono confuso dalla struttura irregolare. Sulla base della descrizione iniziale, mi aspettavo impl a guardare qualcosa di simile:

namespace impl { 
    template<class T> struct Node : T { ... }; 
    template<class T> struct Expr : Node<T> { ... }; 
    template<class S> struct Stmt : Expr<S> { ... }; 
    template<class D> struct Decl : Stmt<D> { ... }; 
    struct Var : Decl<ipr::Var> { ... };  
} 

E sto pensando lo schema completo di queste classi è:

enter image description here

La mia domanda è, perché le tre classi template "interne" non hanno forme parallele, come nella mia versione del codice?

risposta

2

La mia ipotesi migliore viene dal guardare il actual Pivot code che ha

template<class D> struct Decl : Stmt<Node<D>> { ... }; 

invece di Stroustrup

template<class D> struct Decl : Stmt<Expr<D>> { ... }; 

Ciò suggerisce che impl::Stmt non significa necessariamente derivano da impl::Expr dopo tutto, come nell'originale diagramma a rombo (sebbene derivi ancora dall'interfaccia ipr::Expr). Essa non deriva da impl::Expr per Decl e Var, ma lo fa per le altre classi di implementazione, quali impl::For:

struct For : Stmt<Expr<ipr::For> > { ... } 

Io non sono sicuro perché Stroustrup non ha spiegato l'irregolarità. Forse pensava di averlo rimosso cambiando Stmt<Node> a Stmt<Expr>, o forse non lo aveva affatto cambiato (cioè, il codice cambiava dopo averlo copiato) e voleva lasciarlo così com'è senza spiegare ogni dettaglio.

Speriamo che una risposta migliore lo spiegherà.