Stroustrup 线性化 Class 层次结构示例的说明

Explanation of Stroustrup Linearizing Class Hierarchies example

在 Stroustrup 的 C++ 编程语言(第 4 版)中,第 27.4.2 节展示了一种 "linearize" 菱形 class 层次结构以避免开销的技术虚拟基地 classes。他从一个真实项目 (Pivot code analyzer tool) 的菱形图案开始:

线性版本绘制为:

代码大纲为:[=​​20=]

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> { ... };
    }
}

我对不规则的结构感到困惑。根据最初的描述,我希望 impl 看起来像:

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> { ... };    
}

我认为这些 classes 的完整图表是:

我的问题是,为什么"interior"三个impl模板class没有平行形式,就像我的版本一样代码?

我最好的猜测来自查看 actual Pivot code,它有

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

而不是 Stroustrup 的

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

这表明 impl::Stmt 不一定派生自 impl::Expr,就像在原始菱形图中一样(尽管它仍然派生自接口 ipr::Expr)。对于 DeclVar,它不是从 impl::Expr 派生的,但对于其他实现 类,例如 impl::For:

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

我不确定为什么 Stroustrup 没有解释异常情况。也许他认为他通过将 Stmt<Node> 更改为 Stmt<Expr> 来删除它,或者他根本没有更改它(即代码在他复制后更改)并且他想保持原样没有解释每一个细节。

希望有更好的答案来解释它。