处理在 C++ 结构中更改的值

Handle a value being changed in a c++ struct

我有一个描述系统应该如何初始化的结构。然后我有一个方法 returns 对所述结构的引用,以便最终系统的用户可以在初始化后更改某些选项。我希望检测值何时更改并告诉系统的组成部分检查它们所依赖的选项以查看它们是否已被更改并相应地更新自己。

我相信通过重载运算符或类似的东西可以实现这样的事情。我真的不介意开销以及检测和更新代码的样子,我只是希望更改选项的语法看起来干净,并且用户不必在更改后调用 updateOptions() 函数或任何东西。

首先,这可能吗?其次,如果是,我该怎么办?

如果我是你,我会在 setter 函数中为每个选项发出适当的 boost signal,并让订阅者注册这些信号。为了清楚起见,我会使用 class 而不是结构,因为除了暴露的信号、setters 和吸气剂之外,你会希望所有内容都是私有的。

"I have a struct that describes how the system should be initialised. I then have a method that returns a reference to said struct so that the user of the final system can change certain options after initialisation."

这可能是错误的方法。最好对单个属性使用 getter/setter 函数,这样您的 class 可以控制如何对 属性 变化做出反应。

另一种方法是让客户端检索对您的 interned 属性 struct 成员变量的 const 引用,复制它,更改那个并用 setter(更新)函数。与必须调用额外的 update() 函数相比,这将使客户端的过程更加清晰。

在很多情况下,更改单个项目会导致整个设置无效,但更改 2 或 3 可能是有效设置。

如果是这种情况,您可以创建一个 getter/setter 函数对。 getter 函数将 return 结构的副本,而 setter 函数实际上是一个 updateSetting 函数。

这几乎没有开销,并且比每个项目 getter/seeter 更可靠。

我假设你的结构被命名为 Fun

方案一:添加getter、setter并通知

我会为所述结构的每个属性写一个 getter 和一个 setter。它看起来像这样:

struct Fun {
    Fun(System& sys): system{sys} {}

    void setGun(int g) {
        gun = g;
        notify();
    }

    int getGun() {
        return gun;
    }

    void notify() {
            system.updated();
    }

private:
    System& system;
    int gun;
};

当然,引用可以是指针,当然,您必须将结构分离为头文件和 cpp 文件。

解决方案 2:为结构体 Fun

编写一个 get 和 set

这个解决方案的优点是它可能是最快的,当然也是最干净的。

struct System {
    void setFun(Fun f) {
        if (f != fun) {
            // update only if different
            updated();
        }
        // it may be faster if Fun allocates resources
        fun = move(f);
    }

    // do not return by reference
    Fun getFun() const {
        return fun;
    }

private:
    Fun fun;
};