Hi,
now this has always been the single most annoying thing about C++ to me and I would really love to have a solution for it.
Common case: You have a variable in a class that can be read, but should not be edited from outside this class. How do you make the variable easily accessible on the one hand and secure it from editing on the other.
Now as far as I know, there are two ways to implement this:
1) (this is most common)
1 2 3 4 5 6 7 8
|
class cls
{
private:
int foo;
public:
__forceinline int GetFoo() {return foo};
}
|
Pros: The method is secure
2)
1 2 3 4 5
|
class cls
{
public:
int foo;
}
|
Pros: The method is fast and needs little code
So why would someone implement the second approach? Well first of all it looks way better. The class definition isn't bloated with GetThis() and GetThat() and also when using foo somewhere else it can be directly accessed like this:
1 2 3 4
|
cls c;
... = c.foo * c.foo + ...
... = c.foo + ...
...
|
instead of like this:
1 2 3 4
|
cls c;
... = c.GetFoo() * c.GetFoo() + ...
... = c.GetFoo() + ...
...
|
or like this:
1 2 3 4 5
|
cls c;
int cfoo = c.GetFoo();
... = cfoo * cfoo + ...
... = cfoo + ...
...
|
Just imagine having tons of read-only variables like foo. Also even when using __forceinline, which should already be one level above inline (being just some kind of a recommendation to the compiler), I am still not 100% convinced that c.GetFoo() can be as fast as foo.
Therefore I have used the second approach for a long time now, but on larger programs even I (as the author of my own code) lose the plot on which variables can be edited directly and which not.
Currently I am using a macro like this:
1 2 3 4
|
#define READONLY(type, publicvar, localvar, getfunc) protected: type localvar; public: __forceinline type getfunc() {return localvar;}; \
__declspec(property(get=getfunc)) type publicvar;
READONLY(int, foo, myfoo, GetFoo);
|
But again I face some drawbacks:
1) My local variable has to be named differently (here myfoo).
2) I have to declare a function, that I never directly call (here GetFoo).
3) The declaration itself still looks bloated.
In conclusion the issue may look trivial at first, but I'm sure I'm not the only one getting constant headaches about it.