My goal is to fire a event receiver when a value is changed in a class. My solution to this is using get and set functions. However, I do not want any performance problems when reading the values. In the class below:
class Vertex {
public:
const double& GetX() { return _x; } // should inline automatically
const double& GetY() { return _y; } // ' ' ' '
void SetX(const double& x); // complex stuff in source file
void SetY(const double& y); // ' ' ' '
private:
double _x, _y;
}
I put the definition of the getters in the header files, because this should allow them to be inlined.
My question is: is there any way to automatically call a function when a value is changed that does not require me to include function definitions in the header file? Or is there perhaps a visibility level that allows anyone to read the data, but only the class itself to modify it? Or maybe something else?
I know an alternative approach would be manually calling an update function, but that looks ugly:
vertex.X = 5;
vertex.Update();
Thank you in advance.
Edit:
So far I’ve heard some great answers. The solution depends on your goal:
- Easy: getters and setters; not very clean though.
- Clean: property class (or proxy); implementing operators is not as easy though.
However, what about efficiency?
I just worked out a nice trick for the separate read/write-access permissions I speculated about earlier:
class Vertex {
public:
Vertex(double x, double y)
: _x(x), _y(y), X(_x), Y(_y) { } // defined here for readability
void SetX(double x) { _x = x; update(); } // defined here for readability
void SetY(double y) { _y = y; update(); } // update would be the callback
const double& X, Y;
private:
double _x, _y;
}
If all you’re looking for is clean, then probably the cleanest way to do this would be to have a “property” object, like in C#:
(The functions are inline for conciseness on SO, you can move them out if you want.) Then you can do
And every time the value is assigned to, the respective callback will be called. And you can use
v.Xandv.Yin place of wherever you’d use adoubleas well so they behave like normaldoubles (except for the fact that you’d have to implement-=,+=, etc).