Handle a value being changed in a c++ struct

2.1k views Asked by At

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. I wish to detect when a value is changed and tell the component parts of the system to check for options they depend on to see if they've been changed and update themselves accordingly.

I believe such a thing is possible by overloading an operator or something similar. I don't really mind about overhead and what the detection & updating code looks like, I just want the syntax for changing an option to look clean, and for the user to not have to call a updateOptions() function after changes or anything.

Firstly, is this even possible? Secondly, if it is, how would I go about it?

4

There are 4 answers

0
Guillaume Racicot On BEST ANSWER

I will assume your struct is named Fun

Solution 1: Add getter, setter and notify

I would write a getter and a setter for each properties of the said struct. It would look like this:

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;
};

Of course, the reference can be a pointer and of course, you will have to separate the struct to a header and cpp file.

Solution 2: write a get and set for the struct Fun

The advantage of this solution is that it might be the fastest, and of course the cleanest one.

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;
};
6
Luke On

If I were you, I would emit an appropriate boost signal in the setter function for each option, and have subscribers sign up for these signals. I would use a class instead of a struct for clarity, because you'll want everything to be private except for exposed signals, setters and getters.

0
πάντα ῥεῖ On

"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."

That's probably the wrong approach. Better use getter/setter functions for the single properties, such your class can control, how to react on property changes.

Another way would be to let the client retrieve a const reference to your interned properties struct member variable, make a copy of it, change that one and pass it back with a setter (update) function. This would make the process much clearer for the client, than having to call an extra update() function.

0
egur On

In many cases, changing a single item can cause the entire setting to become invalid but changing 2 or 3 can be a valid setting.

If this is the case, you can should create a getter/setter function pair. The getter function will return a copy of the struct and the setter function will effectively be an updateSetting function.

This has very little overhead and is more robust than having a getter/seeter per item.