没有直接的方法,但是你可以写一个虚拟的size()子类可以实现的方法。中间模板类可以自动执行腿部工作。
struct base {
virtual size_t size() const =0;
virtual ~base() { }
};
template<typename T>
struct intermediate : base {
virtual size_t size() const { return sizeof(T); }
};
struct derived : intermediate<derived>
{ };
这确实要求您的层次结构是多态的……但是,基于对象的动态类型而不是其静态类型请求行为是多态行为定义的一部分。所以这不会在普通用例中添加一个 v-table,因为至少你可能已经有了一个虚拟析构函数。
这个特定的实现确实将您的继承树限制在一个层次,而不会进入多重继承[即,从derived 派生的类型不会获得自己的size 覆盖]。有一个稍微复杂的变体可以解决这个问题。
struct base { /*as before */ };
template<typename Derived, typename Base>
struct intermediate : Base {
virtual size_t size() const { return sizeof(Derived); }
};
struct derived : intermediate<derived, base>
{ };
struct further_derived : intermediate<further_derived, derived>
{ };
基本上,这会在层次结构的每个实际层之间插入一个intermediate,每个层都以适当的行为覆盖size,并派生自实际基类型。重复令人作呕。
//what you want
base >> derived
>> more_deriveder
>> most_derivedest
//what you get
base >> intermediate<derived, base>
>> derived >> intermediate<more_deriveder, derived>
>> more_deriveder >> intermediate<most_derivedest, more_deriveder>
>> most_derivedest
几个 mixin 类型的库都使用了这种方案,这样可以将 mixin 添加到现有的层次结构中,而无需引入多重继承。就我个人而言,我很少使用多于一层的继承,所以我不会为增加的复杂性而烦恼,但你的里程可能会有所不同。