Today I decided I was tired of writing tedious accessor/mutator boilerplate, so I wrote a couple of classes to emulate C# properties. You can do something similar with:
1 2 3 4 5 6 7 8
|
class foo {
public:
const int& readonly;
foo() : readonly(m_readonly) {}
private:
int m_readonly;
};
|
But the advantage of C#'s properties is that you can, if you want, handle access and mutation however you want - you can write custom get and set methods for the property:
1 2 3 4 5 6 7 8 9 10 11 12
|
class Foo {
public int TimesAccessed {
get { return mTimesAccessed; }
}
public int ReadOnly {
get { ++mTimesAccessed; return mReadOnly; }
}
private int mTimesAccessed;
private int mReadOnly;
}
|
That is what this code allows. It also has default accessor and mutator functors if you want simple properties so that you can switch to using your own accessors and mutators later on without affecting client code. There are also operator= overloads for properties as l- and r-values so that you can use them as though they were ordinary values. It's also header-only.
There is some overhead, though - currently the accessor and mutators store a reference each to your data, and it also contains its own object of type T which is used if you don't pass a reference to one. There's also overhead in translating the property::get/set methods into the accessor and mutator functor methods. Still, though, I'd say that, in general, flexibility and clarity are more important than performance, programmer time is more expensive than CPU time, and faster algorithms are superior to more optimised code.
Here is the code and an example:
http://ideone.com/cRYmS0
Thoughts? Suggestions?
Ultimately, I don't think I've reduced boilerplate at all (I may even have done the opposite), but whatever.
Here's my to-do list, ordered by priority. Maybe someone can help me with them.
1. Allow assignment from a property to any object of its contained type (the reverse is easy enough and is done).
2. Allow assignment from any readonly property to any writeable property with the same contained type
3. Make readonly/readwrite a template parameter instead of having separate classes, making the syntax prettier (would also solve #2).
4. Reduce memory overhead somehow.
5. Reduce need for boilerplate code (that was, after all, the point of the class...).