c++ public object change should invoke function - c++

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.

Related

Is it possible to override member access operators to detect when any member variable is modified?

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

Using setters in constructor

I'm a Java developer trying to pick up C++. Is it okay to use a setter inside a constructor in order to reuse the sanity checks the setter provides?
For example:
#include <stdexcept>
using namespace std;
class Test {
private:
int foo;
void setFoo(int foo) {
if (foo < 42) {
throw invalid_argument{"Foo < 42."};
}
this->foo = foo;
}
public:
Test(int foo) {
setFoo(foo);
};
};
Yes, it is recommended to do this, basically for the reason you already mentioned.
On the other hand you should ask yourself if you need the setter at all and not directly implement the checks inside the constructor. The reason I am writing this is that setters in general result in mutable state which has many disadvantages as opposed to immutable classes. However sometimes they are required.
Another recommendation: If your class variable is an object and you can modify the constructor of this object, you could put the check into the constructor of this object:
class MyFoo {
public:
MyFoo(int value) {
if (value < 42) {
throw invalid_argument{"Foo < 42."};
}
v = value;
}
private:
int v;
}
This will enable you to use an initialization list in the constructor of your Test class:
Test(int foo) : foo(foo) {}
However, now the check is a property of the class of the variable and no longer one of the owning class.
Yes you can. It's fine as long as your setters are not virtual, because it's inheritance hierarchy in calling right functions as the "this" ptr is not ready yet.
Here is Herb Sutter GOTW on this matter: http://www.gotw.ca/gotw/066.htm
Yes, that's fine as long as it makes sense to have a setter for a particular member variable (have some logic that can't be checked by assignment only for example) . In this example, setFoo could've just taken an unsigned int and the caller would know not to pass negative values. Which in turn could eliminate the check and thus the need for a setter. For more elaborate checks, a setter and usage of that setter in the constructor is just fine.
Short answer: Yes. In fact, your example works.
Long answer: But it is not a good practice. Al least, you have to take care.
In general, a set function works with a constructed object. It is supposed that the invariant of the class holds. The functions in a class are implemented considering the invariant is true.
If you want other functions to be used in a constructor, you would have to write some code. For example, to create an empty object.
For example, if in your class you change setFoo in the future (let's say setFoo changes the member foo only it is larger) you example stop working.
This is okay.
The only situation you cannot call member function is when the base classes are not constructed yet.
can member functions be used to initialize member variables in an initialization list?
I know this doesn't fit your situation. Its just for the sake of completeness:
When you are simply settings member values (without checks like yours in setFoo) it is recommended to use initialization lists in the constructor. This prevents members being "initialized" 2 times: 1. with their default value, 2. with the value that you passed into the constructor.
class Test {
private:
int foo_;
public:
Test(int foo)
: foo_(foo)
{ };
};

Is it possible to specify a private member variable public only for const operations?

I have a member variable, enabled_m, whose value is dependent on a number of variables. Since these invariants should be maintained by the class, I want it to be private:
class foo_t
{
public:
void set_this(...); // may affect enabled_m
void set_that(...); // may affect enabled_m
void set_the_other_thing(...); // may affect enabled_m
bool is_enabled() const { return enabled_m; }
private:
bool enabled_m;
};
Which works, but really my intent is to require a user of foo_t to go through the class to modify enabled_m. If the user wants to just read enabled_m, that should be an allowable operation:
bool my_enabled = foo.enabled_m; // OK
foo.enabled_m = my_enabled; // Error: enabled_m is private
Is there a way to make enabled_m public for const operations and private for non-const operations, all without having to require a user go through accessor routines?
Most engineers will prefer that you use accessor methods, but if you really want a hack-around, you could do something like this:
class AccessControl
{
private:
int dontModifyMeBro;
public:
const int& rDontModifyMeBro;
AccessControl(int theInt): dontModifyMeBro(theInt), rDontModifyMeBro(dontModifyMeBro)
{}
// The default copy constructor would give a reference to the wrong variable.
// Either delete it, or provide a correct version.
AccessControl(AccessControl const & other):
dontModifyMeBro(other.rDontModifyMeBro),
rDontModifyMeBro(dontModifyMeBro)
{}
// The reference member deletes the default assignment operator.
// Either leave it deleted, or provide a correct version.
AccessControl & operator=(AccessControl const & other) {
dontModifyMeBro = other.dontModifyMeBro;
}
};
No, there's no way to restrict modification only to members. private restricts all access to the name; const prevents modification everywhere.
There are some grotesque alternatives (like a const reference, or use of const_cast), but the accessor function is the simplest and most idiomatic way to do this. If it's inline, as in your example, then its use should be as efficient as direct access.
A great deal here depends upon the intent behind exposing the enabled state, but my general advice would be to avoid exposing it at all.
The usual use of your is_enabled would be something like:
if (f.is_enabled())
f.set_this(whatever);
In my opinion, it's nearly always better to just call the set_this, and (if the client cares) have it return a value to indicate whether that succeeded, so the client code becomes something like:
if (!f.set_this(whatever))
// deal with error
Although this may seem like a trivial difference when you start to do multi-threaded programming (for one major example) the difference becomes absolutely critical. In particular, the first code that tests the enabled state, then attempts to set the value is subject to a race condition--the enabled state may change between the call to is_enabled and the call to set_this.
To make a long story short, this is usually a poor design. Just don't do it.

OOP - How should this be done?

I have a class that has the following variables/members:
First Name
Last Name
Age
Address
etc..
I want to create getter-methods for each of them that returns the values. This could become quite large depending on the class.
Is there a quicker or more object-oriented way that would allow me to do this just using one method? The only way I can think about is to have a method that takes a parameter of the name of the variable to be returned; however, the types for the method would change depending on if it was returning a string, int etc..
Does anyone have a solution?
Why do you need those values outside the class? If you have code that is not in Person that calls 4 or 5 Person GetWhatever() methods and glues the strings together, stuffs commas between them and so on, move that code into Person. Do that enough and no code outside Person needs to call your getters.
Some classes are logic-free, they just hold values, and they expect outside objects to do all the work. In C++, using a struct for that makes your intention clear. If you insist that code outside Person needs to arbitrarily access elements of Person, it's probably a struct, not a class. If you insist it's a class, prove it by adding some actual business logic to it.
No, there is no "better" way which is still object-oriented. You should define one public "getter" method for each private member variable which needs to be access outside the class. You should also define a setter method, if the variable is meant to be set from outside the class.
If you want easy to define setter/getter - make it on single member level. Make member template with setter/getter and define is as public element of your class:
template <class Type>
class Member {
public:
Member(const T& value = T()) : value(value) {}
void setValue(const Type& t) { value = t; }
T getValue() const { return value; }
private:
T value;
};
Use it in your class:
class Person {
public:
Member<std::string> firstName;
Member<std::string> lastName;
Member<std::string> address;
Member<unsigned> age;
};
And usage:
int main() {
Person one;
one.firstName.setValue("Joe");
one.age.setValue(33);
}
If your need some constraints (like range checking) then define some RangeCheckingMember template. If you need the members to be dependent on each others - then make relationship between them by pointers/references.
Consider making that parameter lookup using a template member function that takes a default value in a given type.
template<typename ValueType>
const ValueType& get(const KeyType& key, const ValueType& default value) {
...
};
You still have to enumerate (or otherwise list) a KeyType of all your values (or use std::string which might be fine in larger cases) and work back and forth with your storage on the ValueType.
So, this doesn't really help you much until you decide you need arbitrarily large or completely dynamic values. At this point, you need to implement a map which can hold any type which requires either hideous unions or a template wrapper derived class from a common base class used in the map.
The upside to this is that a getKeys() method can present all of the keys available in the class -- something quite useful for dynamic GUIs and message handling.
If you are using a library in which everything subclasses some Object class (QObject for example), you can use a map of (string, object) to hold all your data and then access it with:
Object get(string name) { return memebers[name]; }
members is std::map<std::string, Object>
You will need to use type casts of course.
Button* my_var = static_cast<Button*>(my_class.get("my_button"));
// get returns Object
You can also use Qt's property system if you use Qt. This is not standard c++, but qmake and moc work on many operating systems.
all right.since you know what you want.
void get(int flag, void *return_value)
get the return_value typd casting to what you want.
thanks

Conflict between providing (optional) functionality and encapsulation?

I need to provide a certain operation on the elements of my class Foo. This operation is specific and weird enough that I don't really want to make it a member function. On the other hand, it works on the internals of the class, which I don't want to expose.
Here is the class:
class Foo {
typedef std::map<int,double> VecElem;
std::vector<VecElem> vec_;
public:
void Insert(std::size_t index0, int index1, double d);
// ... other essential functions
};
void Foo::Insert(std::size_t index0, int index1, double d) {
vec_[index0][index1] = d;
}
The operation I need to support is to map the index1 of each element inserted so far to a new index, according to a given old-to-new index map:
void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new);
Given how Foo currently stores its elements this means a complete restructuring of the internal data, but this should not be exposed to the user. But also it shouldn't be a member function.
Is this a typical case of a friend non-member function? Are there any other possibilities? I don't really like the concept of a friend non-member function, because this weird function (which might be only temporarily necessary as a workaround for some problem) will still need to be mentioned inside the "official" class body (which is supposed to never change). But I guess I can't get around that?
What about a public nested class to do the work? Then it could have a MapIndex1 function that automatically gains access to the private members of its enclosing class. When you're done, just remove the nested class.
class Foo {
// ...
public:
void Insert(std::size_t index0, int index1, double d);
// ... other essential functions
class Remapper
{
public:
Remapper(Foo& foo) : foo_(foo) { }
void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new);
private:
Foo& foo_;
};
};
Foo myFoo;
Foo::Remapper remapper(myFoo);
remapper.MapIndex1(...);
An idea for dealing with this scenario is to add a function like:
void Ioctl(int func, void* params); to your class. This function can then be used as a gateways for all of these hackey temporary scenarios as they arise. They can then be safely removed when the requirement disappears without breaking compatibility (unless of course someone unofficially uses them).
True you do lose type safety but it does provide a nice swiss army knife approach for all such problems.
Internally you can define certain integer func values to call a function and cast the params value to whatever you need.