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?
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;
};
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.
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.
"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.
Related
Say I have:
struct foo{
int bar;
int baz;
...
bool flag;
}
Can an access operator -> or . be overridden to detect if bar or any other member variable is modified ?
EDIT:
The purpose is if I have many member variables and any of them is changed, I have a quick way of setting a flag, instead of using setters to encapsulate all the variables, making the code verbose.
Your approach is flawed because even if you override access operators you will not catch pointers writing the actual memory.
If most of the variables have the same type you can use an enum for flags and a single function to set or get a specific variable.
For example:
private:
int bar;
int baz;
public:
enum IntVariables { varBar, varBaz };
bool flag;
void setVariable(int varId, int value) {
flag = true;
if (varId == varBar)
bar = value;
else if (varId == varBaz)
baz = value;
}
I considered the following approach:
Just use a wrapper class that can have any data type, but implement all operations. In this same wrapper class override operators, and use the wrapper class in other class that require any modifications of member variables to be detected.
template <class T>
class wrapper {
private:
T var;
... .. ...
public:
T doSomethingToVar(T arg);
... .. ...
//Wherever the variable is modified send out a notification to whomever needs to detect the changes.
};
Pros:
When declaring variables in whichever class needs to detect modification of variables, it is easy to declare using the wrapper, without much additional code.
To ensure modifications are detected, need to implement functions / getters / setters / overload operators to detect modifications. This is tricky, and requires some thought.
Cons:
Tricky to implement a general purpose wrapper that can detect all modifications, since complex types can have functions that modify themselves in ways one is not aware of.
Notes:
How to ensure that every method of a class calls some other method first?
This answer is a work in progress, and I think it may be useful to others and maybe just cool to know about eventually, so open to comments. Will keep updating.
Update:
While writing out the above answer, I considered a different approach, of shifting responsibility onto the member variable classes:
class DetectChanges{
void onDetectChanges(){
//This function should be called by all implementing classes when the class has changes.
}
Can make it a design choice that all member variables inherit from DetectChanges.
The above two approaches are what I'm considering now. Not a solution yet, but thought I would put it out for comments and see if eventually we can figure something out.
}
I encountered an issue while trying to do something in the process of learning C++ and I am not sure how to handle the situation:
class Command
{
public:
const char * Name;
uint32 Permission;
bool (*Handler)(EmpH*, const char* args); // I do not want to change this by adding more arguments
};
class MyClass : public CommandScript
{
public:
MyClass() : CommandScript("listscript") { }
bool isActive = false;
Command* GetCommands() const
{
static Command commandtable[] =
{
{ "showlist", 3, &DoShowlistCommand } // Maybe handle that differently to fix the problem I've mentioned below?
};
return commandtable;
}
static bool DoShowlistCommand(EmpH * handler, const char * args)
{
// I need to use isActive here for IF statements but I cannot because
// DoShowlistCommand is static and isActive is not static.
// I cannot pass it as a parameter either because I do not want to
// change the structure of class Command at all
// Is there a way to do it?
}
};
Any help would be greatly appreciated! :)
// Is there a way to do it?
No.
Either pass it as parameter, make it static, or make DoShowlistCommand non-static.
There are two potential answers here:
1. about use of non static items in a static functions:
As said in our previous question/answer, this is not possible, unless you'd have in the static function a specific MyClass object (and use object.isActive). Unfortunately, you can't do this here :
your code comments clearly show that you can't add a MyClass parameter to the function call;
the existing parameters don't suggest that you have already a pointer to parent class object;
it would not be adivsable to use global objects in such a context.
2. about what your're trying to do:
It seems that you want to have the function static, because you want to provide it in a table that maps script-commands to function pointers.
Alternative A
If all the function pointers used in commandtable are members of MyClass, you could think of using a pointer to a member function instead of a pointer to a function. The outside object/function that sets isActive on an object, could then refer the pointer to the member function, on the MyClass object it knows.
Alternative B
Revise the design of your code to implement your script engine by using the command design pattern: it's ideally suited for this kind of problems. It will require some refactoring of your code, but it will be so much more maintenable and extensible afterwards !
I don't think there is any way to do it. Here is why:
A static member function is not attached to any particular object, which means it cannot access other members that are not static, since they are attached to an object.
It doesn't look like you need to make it a static member. If you are sure you do - then pass it as a parameter. For example, make a
bool isActive();
function, and pass an argument from it to that function somewhere when you call this 'problematic' one.
You also could change your member variable to static, but it looks like you need it for EACH object, not one-for-all
I'm writing a pretty large library, and I find myself writing almost identical accessors all the time. I already have several dozen accessors such as the one below.
Question: How can I declare/implement accessors to save typing all this repetitive code? (No #defines please; I'm looking for C++ constructs.)
Update: Yes, I do need accessor functions, because I need to take pointers to these accessors for something called Property Descriptors, which enable huge savings in my GUI code (non-library).
.h file
private:
bool _visible;
public:
bool GetVisible() const { return _visible; }
void SetVisible (bool value);
// Repeat for Get/SetFlashing, Get/SetColor, Get/SetLineWidth, etc.
.cpp file
void Element::SetVisible (bool value)
{
_visible = value;
this->InvalidateSelf(); // Call method in base class
// ...
// A bit more code here, identical in 90% of my setters.
// ...
}
// Repeat for Get/SetFlashing, Get/SetColor, Get/SetLineWidth, etc.
I find myself writing almost identical accessors all the time. I already have several dozen accessors such as the one below.
This is a sure design smell that you are writing accessors "for the sake of it". Do you really need them all? Do you really need a low-level public "get" and "set" operation for each one? It's unlikely.
After all, if all you're doing is writing a getter and a setter for each private data member, and each one has the same logic, you may as well have just made the data members public.
Rather your class should have meaningful and semantic operations that, in the course of their duties, may or may not make use of private data members. You will find that each of these meaningful operations is quite different from the rest, and so your problem with repetitive code is vanquished.
As n.m. said:
Easy: avoid accessors. Program your classes to do something, rather than have something.
Even for those operations which have nothing more to them, like controlling visibility, you should have a bool isVisible() const, and a void show(), and a void hide(). You'll find that when you start coding like this it will promote a move away from boilerplate "for the sake of it" getters & setters.
Whilst I think Lightness Races in Orbit makes a very good point, there is also a few ways that can be used to implement "repeating code", which can be applied, assuming we do indeed have a class that have "many things that are similar that need to be controlled individually, so kind of continuing on this, say we have a couple of methods like this:
void Element::Show()
{
visible = true;
Invalidate();
// More code goes here.
}
void Element::Hide()
{
visible = false;
Invalidate();
// More code goes here.
}
Now, to my view, this breaks the DRY (Do not Repeat Yourself) principle, so we should probably do something like this:
void Element::UpdateProperty(bool &property, bool newValue)
{
property = value;
Invalidate();
// More code goes here.
}
Now, we can implement Show and Hide, Flash, Unflash, Shaded etc by doing this, avoiding repetition inside each function.
void Element::Show()
{
UpdateProperty(visible, true);
}
If the type isn't always bool, e.g. there is a position, we can do:
template<typename T>void Element::UpdateProperty(T &property, T newValue)
{
property = value;
Invalidate();
// More code goes here.
}
and the MoveTo becomes:
void Element::MoveTo(Point p)
{
UpdateProperty(position, p);
}
Edit based on previously undisclosed information added to question:
Obviously the above technique can equally be applied to any form of function that does this sort of work:
void Element::SetVisible(bool value)
{
UpdateProperty(visible, value);
}
will work just as well as for Show described above. It doesn't mean you can get away from declaring the functions, but it reduces the need for code inside the function.
I agree with Lightness. You should design your classes for the task at hand, and if you need so many getters and setters, you may be doing something wrong.
That said, most good IDEs allow you to generate simple getters and setters, and some might even allow you to customize them. You might save the repetitive code as a template and select the code fragment whenever needed.
You may also use a customizable editor like emacs and Vim (with Ultisnips) and create some custom helping functions to make your job easy. The task is ripe for automation.
The only time you should ever write a get/set set of functions in any language is if it does something other than just read or write to a simple variable; don't bother wrapping up access to data if all you're doing is make it harder for people to read. If that's what you're doing, stop doing anything.
If you ever do want a set of get/set functions, don't call them get and set -- use assignment and type casting (and do it cleverly). That way you can make your code more readable instead of less.
This is very inelegant:
class get_set {
int value;
public:
int get() { return value; }
void set(int v) { value = v; }
};
This is a bit better
class get_set_2 {
value_type value;
bool needs_updating;
public:
operator value_type const & () {
if (needs_updating) update(); // details to be found elsewhere
return value;
}
get_set_2& operator = (value_type t) {
update(t); // details to be found elsewhere
return *this;
}
};
If you're not doing the second pattern, don't do anything.
I'm a tad late again, but I wanted to answer because I don't totally agree with some other here, and think there's additional points to lay out.
It's difficult to say for sure if your access methods are code smells without seeing a larger codebase, or have more information about intent. Everyone here is right about one thing: access method are generally to be avoided unless they do some 'significant work', or they expose data for the purpose of generic-ism (particularly in libraries).
So, we can go ahead and call methods like the idiomatic data() from STL containers, 'trivial access method'.
Why not use trivial access methods?
First, as others have noted, this can lead to an over-exposure of implementation details. At it's best such exposure makes for tedious code, and at it's worse it can lead to obfuscation of ownership semantics, resource leaks, or fatal exceptions. Exposure is fundamentally opposite of object orientation, because each object ought to manage its own data, and operations.
Secondly, code tends to become long, hard to test, and hard to maintain, as you have noted.
When to use trivial access methods?
Usually when their intent is specific, and non-trivial. For example, the STL containers data() function exists to intentionally expose implementation details for the purposes of genericism for the standard library.
Procedural style-structs
Breaking away from directly object-oriented styles, as implementation sometimes does; you may want to consider a simple struct (or class if you prefer) which acts as a data carrier; that is, they have all, or mostly, public properties. I would advise using a struct only for simple holders. This is opposed to a class ought to be used to establish some invariant in the constructor. In addition to private methods, static methods are a good way to illustrate invariants in a class. For example, a validation method. The invariant establishment on public data is also very good for immutable data.
An example:
// just holds some fields
struct simple_point {
int x, y;
};
// holds from fields, but asserts invariant that coordinates
// must be in [0, 10].
class small_point {
public:
int x, y;
small_point() noexcept : x{}, y{} {}
small_point(int u, int v)
{
if (!small_point::valid(u) || !small_point::valid(u)) {
throw std::invalid_argument("small_point: Invalid coordinate.");
}
x = u;
y = v;
}
static valid(int v) noexcept { return 0 <= v && v <= 10; }
};
I have a silly question! Let's suppose you have a global variable that is used all over the project and you are going to do something when it changes ,for example calling a function .
One simple way is to call your function after every change. But what if this global variable is part of a library and will be used outside .Is there any better solution ?
Presumably you want to find when your variable is modified without tracking down ever reference to it and rewriting all that code that depends on it.
To do that, change your variable from whatever it is now to a class type that overloads operator=, and prints/logs/whatever the change when it happens. For example, let's assume you currently have:
int global;
and want to know when changes are made to global:
class logger {
int value;
public:
logger &operator=(int v) { log(v); value= v; return *this; }
// may need the following, if your code uses `+=`, `-=`. May also need to
// add `*=`, `/=`, etc., if they're used.
logger &operator+=(int v) { log(value+v); value += v; return *this; }
logger &operator-=(int v) { log(value-v); value -= v; return *this; }
// ...
// You'll definitely also need:
operator int() { return value; }
};
and replace the int global; with logger global; to get a log of all the changes to global.
I'd say the easiest way is to create a set method for your variable that calls the function and let it be public, while the variable itself remains private:
//public
void setYourVariable(int newValue)
{
YourVariable = newValue;
YourFunction();
}
//private
int YourVariable;
You need to make an accessor function to set your global variable. Then you can call your special function from that accessor instead of requiring all of the callers to do it themselves.
Just to answer the actual question: No, there isn't a way to determine "when a variable changes" in C++. Technically, if you have enough privilege and the hardware supports it, you could set a "breakpoint on write" for the address of your variable. But it's just a very roundabout way to achieve something that is EASILY achieved by renaming the variable, and then fix all the places where the variable is being accessed to call a function to update the value, and if appropriate also call a function at the same time - as suggested in several answers.
Since u are saying it may get called from out side also, as Kevin said it is good to have Get() and Set(...) methods . Mainly 2 advantages.
1) Through the set u can call a function or do action whenever value changes.
2) You can avoid directly exposing your variable to the outside directly.
I have a C++ class like that:
class Example {
public:
int getSomeProperty(int id) const;
private:
lazilyLoadSomeData();
}
Basically getSomeProperty() return some data that has been loaded using lazilyLoadSomeData(). Since I don't want to load this data until needed, I'm calling this method within getSomeProperty()
int Example::getSomeProperty(int id) const {
lazilyLoadSomeData(); // Now the data is loaded
return loadedData[id];
}
This does not work since lazilyLoadSomeData() is not const. Even though it only changes mutable data members, the compiler won't allow it. The only two solutions I can think of are:
Load the data in the class constructor, however I do not want to do that, as lazily loading everything makes the application faster.
Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.
Any suggestion on what would be the proper way to handle this, without having to cheat the compiler (or giving up on const-correctness altogether)?
You could make a proxy member object which you declare mutable and which encapsulates the lazy-loading policy. That proxy could itself be used from your const function. As a bonus you'll probably end up with some reusable code.
I would forward the call to a proxy object which is a mutable member of this class, something like this:
class Example {
public:
int getSomeProperty(int id) const
{
m_proxy.LazyLoad();
return m_proxy.getProperty(id);
}
private:
struct LazilyLoadableData
{
int GetProperty(int id) const;
void LazyLoad();
};
mutable LazilyLoadableData m_proxy;
};
Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.
No, it's not making some changes, at least not from the viewpoint whoever called getSomeProperty. All changes, if you're doing it right, are purely internal, and not visible in any way from the outside. This is the solution I'd choose.