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.
Related
class MyClass{
public:
MyClass();
void memberFunction();
private:
int myVariable_; // can i declare it here?
};
void MyClass::memberFunction(){
int myVariable_; //or here?
}
//variable "myVariable_" is used only inside "memberFunction()"
If it's only used within a function, and it doesn't need to exist longer than that function, then you're talking about a local variable.
If you need it to persist between calls, you need a property.
In other words, do you need the value stored in myVariable_ to persist to the next call?
You should keep in mind The Principle of Least Privilege. It means every thing should be encapsulated where it is needed.For example, If you need a variable that must be accessible within the function, it suppose to be in the function. If a function is not allowed to change the data, it must be declared const.
This article may help you understanding Here.
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 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.
I create a class like this
class myClass {
public:
int addMeOne;
void Invoked() { .... }
};
I created an object of it and used to send it to all other modules of my program by reference . Everyone used to increment the addMeOne variable by 1 . some even used to add twice but that’s not the point .
With this , now I want whenever someone alters addMeOne , my function Invoked() should get called .
Please note that the right strategy would have been that I should have allowed addMeOne to be exposed outside by some function and inside that function I could call Invoked . However , the interface cannot be altered now since this is now exposed to the all others and should not be modified. How can I correct this . ?
You have to make a method that would assign the value to the addMeOne variable, this is known as a setter method, and make the variable itself private.
There is no way to trigger a function upon changing an integer variable, I believe.
One alternative which would change the interface, but would not require changing the code outside is to define a class that would mimic the behavior of an integer, i.e. implement operator++ etc., and change addMeOne to this type.
You needv to read up on encapsulation. Without providing a locked down getter / setter interface to addMeOn there is no way to guarantee control over its use.
Don't be afraid to change the interface. It will not be a big task for anyone using it to change and they should be clear that what you are doing in changing it is to provide value for their benefit.
Should you preserve the ABI of this class, or just the syntax that its clients use?
If you can change the type of addMeOne, preserving the ability to write addMeOne++ etc, you can define a class and the relevant operators for it - then make addMeOne to be an instance of this class. Certainly, now addMeOne operators can do anything -- including invocations of some MyClass member functions.
Psuedo-code:
class Proxy
{
public:
Proxy(YourClass *parent) : parent_(parent), value_(0)
{}
void operator++()
{
++value_;
// doAnything with parent_
}
// accessors, cast operators etc...
private:
YourClass *parent_;
int value_;
};
class YourClass
{
public:
YourClass() : addMeOne(this)
{}
Proxy addMeOne;
};
Really, it's probably worth telling all clients to use a method instead of a public variable. You either need to change the class, the clients or both.
There's no way around it. Do it again and do it right. Take the hit.
There are tricks: Once you expose a member variable one thing that you can do is to replace int addMeOne with some other variable with the same name but a different type. countedint addMeOne. The countedint class you would have to write such that it behaves like an int but that the assignment, incrementation and so on also counts the number of times they have been used. For example
countedint & operator ++(){
m_value++;
m_number_of_uses++;
return *this;
}
countedint & operator --(){
m_value--;
m_number_of_uses++;
return *this;
}
You would probably also need to have a cast operator to int and you could count the number of uses there too.
Use can turn addMeOne into a proxy.
class myClass
{
class addMeOneProxy
{
public:
addMeOneProxy(myClass &s) : parent(s) {}
// This gets called whenever something tries to use the addMeOne
// member variable as an integer.
operator int() const
{
return parent.addMeOne;
}
// This gets called whenever something assigns a value to addMeOne.
int operator=(int val)
{
parent.Invoked();
return val;
}
// You could also implement an operator++ or whatever else you need.
private:
myClass &parent;
};
public:
void Invoked();
addMeOneProxy addMeOne;
};
Of course, if you decide to make Invoked() private at some point, you will need to make myClass a friend class of addMeOneProxy so that addMeOneProxy can call the Invoked member function.
I certainly concur with the other commenters that you should really have getter and setter functions for this, but I also understand that developers often have limited power to control and change the world they live in. So, the proxy is how you can do it if you aren't able or allowed to change the world.
I am currently trying to make sure that a member function of one class is only called by a member function of another class.
The architecture is imposed and cannot be changed, the port means that some logic has to be done in a.call() before calling b.call(). a.call() therefore calls b.call() to simplify things and make sure the order is respected.
I found this answer to my question. Only, the problem is that I am using classes, and the two classes have the same member function name and so the #define tries to replace all the occurrences which have different prototypes.
I recommend the passkey pattern. It's very good for giving fine grained control on who can do what with your function.
Off the top of my head, options would be:
Make b.call private and make b add a or a.call as a friend
Turn b.call into a class and put the body into a a private constructor with a or a.call as a friend
grep the source code for b.call, make sure the only call is in a.call, and add a comment at the declaration saying "if you call this function you will be fired"
Change b.call to take at least one of the values it needs as a parameter (even if it ignores it and uses the value from somewhere else)
Can you change b.call to take a reference to a? This way, b.call can call a.call itself:
struct A {
void call() {
// do stuff
}
};
struct B {
void call(A & a) {
a.call();
// do stuff
}
};
This makes sure that a.call is always called before the rest of b.call is executed.
How about using a flag?
a.call()
{
// ...
flag = 1;
b.call();
flag = 0;
}
b.call()
{
if (flag == 0)
return;
// ...
}
If you program for certain platform (say x86 or x64), and you know the calling convention (e.g. cdecl), then you can get this info from the stack
Say you want to check the object that called the function, so use the this pointer that is pushed to the stack prior to calling the member function: get the this pointer and compare it with the object that you want (this_pointer == a)
If you want to check certain function, get the caller address from the stack and check against that function: caller_address == A::call. If it's a virtual function, use the this pointer to get the vtable.
Depending on the calling-convention and the order of pushing variables on the stack, you may have to check first the input variables sizes, in order to get to the information you need.