如何在继承级别的多个实例之间共享相同的数据?

时间:2017-02-14 10:46:27

标签: c++ inheritance static

我想实例化相同继承级别的多个对象,并且对于这些级别中的每一个都使用相同的数据。所以我考虑一个类的继承和静态成员。

这是我的attempt

#include <iostream>

class Father
{
public:
    static int sValue;

    inline int GetValue() { return sValue * 10; }
};

class Child1 : public Father
{
public:
};

class Child2 : public Father
{
public:
};

int Father::sValue = 0;

int main()
{
    Child1 child1_1;
    Child1 child1_2;
    Child2 child2_1;
    Child2 child2_2;    


    child1_1.sValue = 1;
    child2_1.sValue = 2;    

    std::cout << child1_2.GetValue() << std::endl;
    std::cout << child2_2.GetValue() << std::endl;
}   

在我的示例中,Child1个实例应返回10 GetValue(),两个Child2实例应使用GetValue()返回20。由于功能相同,我不想为每个孩子覆盖它(这就是为什么我把它放在Father中)。

问题是,Child1个实例还会返回20个GetValue()

因此static在&#34; main&#34;之间共享父母,而不是孩子。

由于sValue使用GetValue()值,因此将其放在此处是正确的。但我无法将静态/相同的数据分开。

你会怎么做?

3 个答案:

答案 0 :(得分:2)

splrs用户已正确识别您的问题,解决方案是正确的。您需要两个不同的函数和两个不同的静态对象。您可以使用模板避免重复代码:

template<class Child>
struct Father {
    static int sValue;
    int GetValue() { /* ... */ }
};

struct Child1 : Father<Child1> {};
struct Child2 : Father<Child2> {};

这个成语被称为奇怪的重复出现的模板模式

当然,现在没有共同的父母。如果需要,可以从非模板库继承模板:

struct FatherBase {};

template<class Child>
struct Father : FatherBase { /*...*/ };

而且,如果您需要从基础访问不同版本的GetValue,那么您需要一个虚函数:

struct FatherBase {
    virtual int GetValue() = 0;
};

template<class Child>
struct Father : FatherBase {
    // ...
    int GetValue() override { /* ... */ }
};

答案 1 :(得分:1)

当您致电Father::sValuechild1_1.sValue = 1;时,您正在修改child2_1.sValue = 2;有一个属于Father的实例,因此您可以访问它(通过针对类或实例的方法)在调用GetValue()之前,您将获得所设置的任何内容。

如果您需要Child1Child2版本,请将静态成员和方法添加到这些类中。

答案 2 :(得分:1)

我认为以下内容可能是您所追求的:

class Father
{
public:
    inline int GetValue() { return DoGetValue() * 10; }
    void SetValue( int value ) { DoSetValue( value ); }

protected:
    virtual int DoGetValue() = 0;
    virtual void DoSetValue( int value ) = 0;
};


class Child1 : public Father
{
public:
    static int sValue;

protected:
    int DoGetValue() override { return sValue; }
    void DoSetValue( int value ) override { sValue = value; }
};

class Child2 : public Father
{
public:
    static int sValue;

protected:
    int DoGetValue() override { return sValue; }
    void DoSetValue( int value ) override { sValue = value; }
};

int Child1::sValue = 0;
int Child2::sValue = 0;

int main()
{
    Child1 child1_1;
    Child1 child1_2;
    Child2 child2_1;
    Child2 child2_2;    


    child1_1.SetValue( 1 );
    child2_1.SetValue( 2 );    

    std::cout << child1_2.GetValue() << std::endl;
    std::cout << child2_2.GetValue() << std::endl;
}