【发布时间】:2014-06-25 10:28:25
【问题描述】:
简化问题
我有以下几点:
class Foo {};
class Bar : public Foo {};
template <class T>
class TemplatedClass : public T {};
class SpecializedClass : public TemplatedClass<Foo> {};
我需要一个新课程,
class RespecializedClass : public TemplatedClass<Bar> {};
但是这个新类在各方面都与SpecializedClass 相同,只是它专门针对Bar,一个派生自Foo 的类。 可以简单地复制粘贴SpecializedClass,但是我必须维护两个应该相同的代码行。
有没有办法从SpecializedClass派生RespecializedClass,但进一步将模板数据类型特化为子数据类型?
原始问题(更接近我的实际问题)
我得到了以下类层次结构:
class X {};
class A {};
template <class T>
class B : public T, public A {};
class C : public B<X> {};
class D : public C {};
我无法触及X、A、B、C 和D 背后的任何来源。我只能从它们派生和扩展。
现在,我从X 派生了一个新类——称之为小写x。 (我通常不会在一个设置中使用X 和x,但在这种情况下,视觉相似性在这种情况下很有帮助。)
class x : public X {};
我需要的是一个与D 相同的类,但模板是x 而不是X。
当然,我可以简单地复制粘贴 C 和 D 并将它们专门用于 x,如下所示:
class c : public B<x> {};
class d : public c {};
但是每当C 和D 被修改时,我都必须维护这个代码行。
有没有办法做类似的事情
class d : public D, public B<x> {};
要在层次结构中“重新专门化”模板的数据类型?
注意
无需阅读本段;事实上,它可能比启发更令人困惑。 我需要在x 而不是X 上模板化d 的原因是x 和X 封装了数据库表,而B 有被写来更新它模板化的任何表。为了更接近事实,我正在使用的基础架构为我们所有的数据库表自动生成封装类。在数据库字典中,可以配置从另一个表继承所有字段和键的“派生”表,然后使用附加字段和键扩展该表。基础设施不仅为这些“派生”表自动生成封装类,而且实际上将它们表示为它们各自父类的派生类。所以,事实上,我实际上并不是在编码 x——它是为我自动生成的,作为X 的子类。现在我可以更准确地说,我需要的是一个类,它可以执行所有操作 D 确实,但在数据库表x 上操作,而不是X。
【问题讨论】:
-
您为什么不想使用一个类型参数 (
class T) 制作C和D(或其副本)类模板? -
不幸的是,
X、A、B、C和D都是我公司基础架构的一部分。我可以派生和扩展这些类,但不能修改它们。除非我误会你了。 -
所以,从本质上讲,您希望 d 和 D 从同一个接口派生,以便能够在某些算法中使用 d 代替 D?
-
@didierc - 我认为这是一种有效的表达方式。但我不仅想要相同的界面,还想要相同的代码。也就是说,任何适用于
X的代码也应该适用于x,对吧?我实际上不需要修改D的代码。我只需要T是专门的,因为B中有一些代码(同样,我无法触及)如果它专门用于X,它将写入一个数据库表,或者如果它专门用于另一个数据库表x。 (有关详细信息,请参阅注释。) -
任何代码在 d 和 D 上工作的唯一方法是它们共享相同的祖先(也可以是任何一个类)并且该代码在那个共同的祖先上工作。由于您的框架不关心表“共性”,并且您无法在 C++ 中开箱即用(afaik):您必须实现一个适配器类,该类将公开通用接口并包装 D 或 d,或者编写模板该界面上的代码。
标签: c++ templates inheritance template-specialization derived-class