Stroustrup线性化类层次结构的解释示例

时间:2015-01-18 22:40:54

标签: c++ diamond-problem

在Stroustrup的 C ++编程语言(第4版)中,第27.4.2节显示了一种技术,以便线性化"钻石类层次结构,以避免虚拟基类的开销。他从真实项目(Pivot code analyzer tool):

开始钻石图案

enter image description here

线性版本绘制为:

enter image description here

enter image description here

代码大纲是:

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

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

enter image description here

我的问题是,为什么不要&#34;内部&#34;三个impl模板类具有并行形式,如我的代码版本?

1 个答案:

答案 0 :(得分:2)

我最好的猜测来自查看有{/ 3>的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)。它并非来自impl::ExprDecl的{​​{1}},但它适用于其他实现类,例如Var

impl::For

我不确定为什么Stroustrup没有解释这种不规则性。也许他认为他通过将struct For : Stmt<Expr<ipr::For> > { ... } 更改为Stmt<Node>来删除它,或者可能根本没有更改它(也就是说,代码在复制之后更改了)并且他希望保留原样没有解释每一个细节。

希望更好的答案可以解释它。