继承静态变量成员,但将其分别共享给每个继承类

4
如果类继承具有静态变量成员的基类,则它们只有一个成员与所有继承类共享。
我有几种继承类,并且每个类都有许多实例。我希望每个继承类都有一个单独的静态成员,可以与其所有实例共享。如何实现呢?
谢谢,对我的差劲英语表示抱歉。
编辑:
class a{
static int var;};
class b::a{};
class c::a{};

现在,我希望所有的 b 实例都具有相同的变量,并且所有的 c 实例也具有相同的变量,但是 b 的变量将不同于 c 的变量。
对于我的英语再次道歉,如果您能纠正我,请务必这样做。

单独的静态成员与其所有实例共享。你自相矛盾。 - FailedDev
检查@BatchyX的答案。它非常准确 :) - FailedDev
3个回答

10
你可以使用CRTP来解决这个问题:
struct YourBaseBaseClass {
    // put everything that does not depend on your static variable
};

template <YourSubclass>
struct YourBaseClass : YourBaseBaseClass {
    static Member variable;
    // and everything that depend on that static variable.
};

struct AClass : YourBaseClass<AClass> {
     // there is a "variable" static variable here
};

struct AnotherClass : YourBaseClass<AnotherClass> {
     // which is different from the "variable" static variable here.
};

AClassAnotherClass都有一个静态变量(类型为Member),但第一个是来自YourBaseClass<AClass>的静态变量,而另一个是来自YourBaseClass<AnotherClass>的静态变量,这两个类是不同的。

YourBaseBaseClass是可选的,但如果您想使用YourBaseBaseClass*指针操作AClassAnotherClass,则需要它(因为您无法拥有一个YourBaseClass*指针,因为YourBaseClass不是一个类)。

并记得定义这些静态变量。


+1,但通常的做法是在涉及到继承或方法时使用类,而不是结构体。还要在YourBaseBaseClass中添加(空的?)虚析构函数也很重要。 - smerlin
非常好,谢谢BatchyX。我仍然希望有更简单的解决方案。 - yoni
1
@smerlin:是啊,我应该把它放在头文件中,定义静态变量,用真正的代码代替注释,记录这些类,typedef超类,编写测试用例,等等... - BatchyX

2
在这种情况下,您不能将静态成员放在基类中。但是,您可以尝试将其放在派生类中,并通过调用基类中的静态方法来访问它。因此,Derived和Derived2的实例可以共享不同的静态成员。如果调用其GetStaticValue()方法,则强制派生类定义名为value的静态成员。
template <typename T>
class Base
{
public:

    static int GetStaticValue()
    {
        return T::value;
    }
};

class Derived : public Base<Derived>
{
    friend class Base<Derived>;
private:
    static int value;
};

int Derived::value = 1;

class Derived2 : public Base<Derived2>
{
    friend class Base<Derived2>;
private:
    static int value;
};

int Derived2::value = 2;

int main()
{
    Derived d;
    Derived da;
    int ret = d.GetStaticValue();
    ret = da.GetStaticValue();
    // As everything is static you don't need to instantiate the Derived classes
    ret = Base<Derived>::GetStaticValue(); 

    Derived2 d2;
    Derived2 d2a;
    ret = d2.GetStaticValue();
    ret = d2a.GetStaticValue();
}

0

静态成员与非静态成员不同。静态成员被称为类变量,而非静态成员被称为实例变量。这是因为非静态成员属于特定对象(类的实例),而静态变量是共享的。

因此,静态成员不遵循相同的继承规则,并保留定义它们的类的属性。


所以我猜我应该补充一下,如果 A 是基类而 B 是派生类,你可以通过 "A::member" 在 B 的方法中访问静态成员。 - Bartek Banachewicz
@user983064 这不是我的问题。请查看我的编辑,也许现在更清楚了。 - yoni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接