
Hello. I've been trying hard to implement the best possible properties sytem in c++ (version 0x). For now, I'm quite satisfied with the result, but it can be improved a little. The properties are implemented in a header called (surprisingly!) Property.hpp Classes: template TROProperty and TRWProperty for trivial properties, which are those which you can use very straightforward without defining setters or getters and it stores the property value inside. templates RWProperty and ROProperty, for which you need to define a storage (if needed) and getters and setters. FEATURES: - You can define a getter as a function that returns *ANYTHING* and it will deduce parameters, constness and everything it needs. - You can define a setter as a function that returns void and takes one parameter. The deduction machinery will do the rest. So, for trivial properties there is little to explain: class Person { public: TROProperty<unsigned int> Age; Person(int age) : Age(age) {} }; int main(int argc, char * argv[]) { Person p(26); cout << p.Age << endl; } For elaborated properties, you have freedom in defining the get and set functions, as long as the get function gets just one parameter and the set function sets one parameter and returns void. The usage of elaborated properties is done through a macro: class Agenda { typedef Agenda ClassName; //Needed for elaborated properties. vector<Person> persons_; Person * getCurrentPerson() { return persons_[Position]; } public: TrivialProperty<int> Position; PROP_ROPROPERTY(CurrentPerson); .... Agenda() : PROP_PROPERTY_INIT(CurrentPerson) {}; }; And now it's ready to be used. For now the features are: -Implicit conversion to the underlying type. -Operator overloading (just a sample of the possible operators, just implemented operator++ and some others) -Comparison operators... -Construction assignment, etc from any other property that has a convertible type or from a data type that makes sense. - Move and copy construction where it makes sense. - Compare, for example, a Property<int> to an int or another property with a convertible value to a Property<int>. If it makes sense, it must work. The same for any other operator. - You can obtain the underlying type for a property through operator(), which makes sense in some contexts. For example, suppose you have a class Person with properties Name, SurName and Age and a class Agenda with a property CurrentPerson which returns a pointer to a Person. You can do like this: string name = agenda.CurrentPerson().Name; you can assign Name to a string or any other property that accepts a string (untested but you could). But you don't need operator() when implicit conversion takes place. personsbyage_[aperson.Age] //No need for operator(), implicit conversion Caveats: ROProperty TROProperty I cannot enforce a private operator= because for that I need a workaround I don't know of or extended friend declarations, which are part of c++0x. So for now, these properties are exactly the same as their writeable counterparts without read-only enforcement. In the implementation part, for elaborated properties I have a template like this: template <class Getter, class Setter> class RWProperty; The same goes for ROProperty. Just with that and the macro to ease the writing of properties, you can get a property. These properties must be constructed with the this pointer AND the pointer to member functions. I'm experimenting (but I can't find a way to do it) with something like this: template <class Getter, class Setter, Getter, Setter> class RWProperty; so that the construction of properties wouldn't need the pointers, because they would be passed as template parameters. But inside the template I have an ambiguity problem. Getter and Setter are pointer to member function types and Getter and Setter parameters are the addresses. For now I've found the properties very usable. The only caveats are the enforcement of operator= and the passing of pointer to members as part of initialization. If I can solve those, we can get a good properties implementation of properties and the initialization of elaborated properties would be just with the this pointer (and a value if you want to initialize with a value). This is a work in progress. For now I've used c++0x, but I think I can use BOOST_TYPEOF (maybe) and some other things in order to translate it to current c++. The code is attached. It's an (unfinished) miniapplication of an Agenda made in gtkmm compiled under g++ 4.5 svn. Take a look at the Property.hpp and the application and tell me what you think. I would like to be able to pass pointer to member functions as template arguments in order to avoid initialization of pointers as parameters. compile with: g++ -std=c++0x `pkg-config gtkmm-2.4 --libs --cflags` Person.cpp Agenda.cpp Window.cpp main.cpp -o Agenda You can just add people with "Añadir" Button and traverse with < and > button. It does not do anything special, it's just to test properties.