Объяснение примера линеаризации иерархий классов Строструпа
В языке программирования Строструпа C++ (4-е изд.), раздел 27.4.2 показывает метод "линеаризации" иерархии классов diamond, чтобы избежать накладных расходов виртуальных базовых классов. Он начинает с алмазного узора из реального проекта (Pivot Code analyzer tool):
Линейный вариант рисуется следующим образом:
И
Схема кода такова:
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> { ... };
}
И я думаю, что полная диаграмма этих классов:
Мой вопрос: , почему "внутренние" три класса шаблонов impl
не имеют параллельных форм, как в моей версии кода?
1 ответ:
Мое лучшее предположение исходит из того, что я смотрю на фактический сводный код , который имеет
template<class D> struct Decl : Stmt<Node<D>> { ... };
Вместо Строструпа
Это предполагает, чтоtemplate<class D> struct Decl : Stmt<Expr<D>> { ... };
impl::Stmt
не обязательно выводится изimpl::Expr
, как в исходной диаграмме алмаза (хотя она все еще выводится из интерфейсаipr::Expr
). Он не является производным отimpl::Expr
дляDecl
иVar
, но он делает это для других классов реализации, таких какimpl::For
:struct For : Stmt<Expr<ipr::For> > { ... }
Я не уверен, почему Страуструп не объяснить неровность. Возможно, он думал, что удалил его, изменив
Надеюсь, что лучший ответ объяснит это.Stmt<Node>
наStmt<Expr>
, или, возможно, он вообще не изменял его (то есть код изменился после того, как он скопировал его), и он хотел оставить его как есть, не объясняя каждую деталь.