如何解决在重用基本模板实现时替代虚拟继承
在我正在处理的一个项目中,我们使用一种模式,其中我们有定义接口的纯抽象类,以及可以使用不同模板参数实例化的模板实现,这些模板参数用于许多事情,包括依赖注入。类似的东西:
struct Base {
virtual int getVal() = 0;
};
template <typename DI>
struct BaseImpl : public Base {
int getVal() override { return DI::k_Val; }
};
我想问题零是这是否是已知/常见/正式模式,如果是,它的名字是什么?
一个常见的需求是扩展 Base
接口,比如 Inherited
。任何 Inherited
对象仍应多态地用作 Base
,但也应用作 Inherited
,它可以定义其他方法。类似的东西:
struct Inherited : public Base {
virtual int getotherVal() = 0;
};
问题在于在 BaseImpl<>
中重复使用 InheritedImpl<>
的实现。因为 InheritedImpl<>
需要从 Inherited
和 BaseImpl<>
继承,所以我们遇到了 "dreaded dimond" 问题,所以我们必须使用虚拟继承。请参阅 godbolt 中的工作示例。
struct Base {
virtual int getVal() = 0;
};
template <typename DI>
struct BaseImpl : public virtual Base {
int getVal() override { return DI::k_Val; }
};
struct Inherited : public virtual Base {
virtual int getotherVal() = 0;
};
template <typename DI>
struct InheritedImpl : public Inherited,public BaseImpl<DI> {
int getotherVal() override { return DI::k_OtherVal; }
};
void useBase(Base& base) {
std::cout << "getVal: " << base.getVal() << std::endl;
}
void useInherited(Inherited& inherited) {
std::cout << "getotherVal: " << inherited.getotherVal() << std::endl;
}
struct DI {
static constexpr int k_Val = 1;
static constexpr int k_OtherVal = 2;
};
int main() {
auto base = std::make_unique<BaseImpl<DI>>();
auto inherited = std::make_unique<InheritedImpl<DI>>();
useBase(*base);
useBase(*inherited);
useInherited(*inherited);
}
getVal: 1
getVal: 1
getotherVal: 2
因为 issues with virtual inheritance,如果可能的话,我想避免在这里使用它。在这种情况下有其他选择吗?这可能是代码异味吗?任何架构建议?
解决方法
基本模式是:
struct Base{
virtual int count()const=0;
};
template<class X,class B=Base>
struct CountImpl:B{
int count()const final{ return X::count; }
};
现在我们可以 CountImpl<Foo,Extended>
对继承进行变基。
可以完成更高级的东西,包括插件方面等。在较简单的情况下这是不值得的,应该避免确实需要的复杂情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。