【发布时间】:2018-01-07 10:43:50
【问题描述】:
想解决我的问题很长一段时间,当我没有其他想法只能在这里问时,我终于明白了。
我有以下问题。
短版。如何从基类继承静态字段,但在每个派生类中使其唯一并保持将这些类向上转换为父类的可能性?
长版。我需要为一组类创建某种基本接口。这些类中的每一个都需要有一个静态字段和一个静态方法。但我希望能够将所有这些类作为参数传递给一个使用这些静态成员的通用函数。所以我在考虑从一个基类继承它们。
但我当然不能简单地继承静态成员并期望它们在每个子类中都是唯一的。我试图使用奇怪重复模板模式(CRTP),但它迫使我也制作这个通用函数模板,并在每次调用期间直接给它类名。这对我不利。
此外,当使用多级继承时(即,当我想从派生自此模板基类的类派生一个类时)时,我在使 CRTP 工作时遇到问题。有什么办法可以达到我的需要吗?
我知道已经有人问过类似的问题,但其中大多数作者都对 CRTP 感到满意。对我来说,这似乎还不够好。
//pseudo-code for what I need, doesn't work of course
class Base {
public:
static int x;
static int GetX() {return x;}
}
class Derived : public Base {};
class NextDerived : public Derived {};
class NextDerived2 : public Derived {};
void Foo(Base& a) {a.x = 10;}
int main {
NextDerived d;
NextDerived2 d2;
Foo(d);
Foo(d2); //both Foos modify different static variables
}
//CRTP attempt
template <class C>
class Base {
public:
static int x;
static int GetX() {return x}
};
class Derived : public Base<Derived> {};
int Derived::x = 0;
template <class C>
void Foo(Base<C>& b) {
b.x = 10;
return;
};
int main() {
Derived d;
Foo<Derived>(d);
}
【问题讨论】:
-
这听起来像是模板的工作。
-
CRTP 是您问题的解决方案。我看不到任何其他方法可以为每个子类设置不同的静态变量。 CRTP 解决方案有什么问题?
-
你为什么写
Foo<Derived>(d);?Foo(d);应该没问题。 -
为什么要将它们保留在基类中?将静态数据移动到派生类并使用虚拟接口来访问它们。您可以在派生类上使用 CRTP。或者在基类上使用 CRTP 并制作一个更通用的基类,使用 virtual 来访问您需要的内容。
-
@AndreasH。哇。这么简单的错误,我因此浪费了好几天。我一定在某处听说过这种调用模板函数的方式。我还不太擅长模板。我刚刚测试了你的建议,它就像一个魅力。我什至可以从 Derived 派生另一个类,它仍然有效。似乎是一个解决方案:D
标签: c++ inheritance interface static crtp