C++让两个子类共享基类中的一个变量

C++ Have two child classes share a variable from their base class

本文关键字:变量 基类 一个 子类 两个 C++ 共享      更新时间:2023-10-16

假设我有三个类:Base、A和B.

Base是a类和B类的基类。

Base有一个变量val,a和B可以访问该变量。

如果我可以通过类A设置val变量,并且它反映在类B中,我该如何使它工作?

例如:

我知道下面的代码不起作用,因为我正在创建一个类型为a和b的对象。

我想做的是简单地让a和b共享同一个变量,这样每当a对它做什么时,它都会反映在b中。

a aa;
b bb;
aa.SetVal(50000);
cout << aa.GetVal() << endl;
cout << bb.GetVal() << endl;

最后,我希望cout的两行都能打印出50000。

EDIT:类A和B将执行不同的操作,只需要能够访问/更改基础中的val变量

您可以使该成员成为基类的静态成员,然后所有派生类都可以访问它,但是任何更改静态成员的派生对象都会对其他对象进行更改。

class Base
{
public:
    int GetVal()
    {
        return val;
    }
    void SetVal( int newVal )
    {
        val = newVal;
    }
private:
    static int val;
};
// Need to instantiate the static variable somewhere
int Base::val = 0;
class A : public Base
{};
class B : public Base
{};
class Base {
    static int value;
public:
    virtual ~Base() { }
    void setVal(const int& val) {
        value = val;
    }
    int getVal() const {
        return value;
    }
};
int Base::value = 0;
class A : public Base {
};
class B : public Base {
};
#include <iostream>
int main() {
    A a;
    B b;
    a.setVal(20);
    std::cout << b.getVal(); // 20
}

这是引用的工作,而不是类的工作。只需有一个类X并创建对对象的引用:

X  aa;
X& bb = aa;
aa.SetVal(50000);
std::cout << aa.GetVal() << std::endl;
std::cout << bb.GetVal() << std::endl;

输出为:

50000
50000

记住,在工作中要始终使用正确的工具,并保持简单。


主要目标是,这两个类将做不同的事情,但需要能够访问和共享单个变量。

解决这个问题的一个想法是提取另一个类中的公共变量,即S,它将被传递给AB,如下所示:

std::shared_ptr<S> s = new S();
A aa(s);
B bb(s)

现在,aabb共享同一个S对象,并且可以很容易地对其进行修改。注意,AB的构造函数也应该存储std::shared_ptr<S>

class A { // and B
private:
    std::shared_ptr<S> s;
public:
    A(std::shared_ptr<S> as) : s(as) {}
};

变量s将持续到aabb中的任何一个处于活动状态:当aabb都被释放或超出范围时,变量s也将被释放。

如果公共变量的类型应该在堆栈上,您也可以只使用引用,但要注意aabb和该变量的生存期:

int s = 0;
A aa(s);
B bb(s);

带有:

class A { // and B
private:
    int& s; // or any other type
public:
    A(int& as) : s(as) {}
};

但根据一般经验,我会避免对象之间的共享状态。大多数时候,根据上下文,您可以重构代码并消除共享依赖关系。

如果基类中的共享值是静态的,那么派生类的所有实例都将看到一个基类成员。

如果该值不是静态的,那么无论该值是否在基类中,类的每个实例都将有自己的副本。

我不知道你想做什么。你想让A和B的所有实例共享相同的值吗?如果是,请在基类中将其声明为静态。如果没有,你想如何选择哪一个分享价值?