Re: Properties with non standard C++ (REALLY SORRY ABOUT THAT)
Try out this code:
#include <iostream>
#include <string>
using namespace std;
template<typename class_T, typename T, typename const_reference_T =
const T&> class property {
public:
typedef T value_type;
typedef const_reference_T const_reference_type;
typedef class_T class_type;
typedef const_reference_type (class_type::*get_type)() const;
typedef void (class_type::*set_type)(const_reference_type);
typedef value_type& (class_type::*get_ref_type)();
public:
property(class_type* p_obj, get_type p_get_fun, set_type p_set_fun,
get_ref_type p_get_ref_fun) : m_p_obj(p_obj), m_p_get_fun(p_get_fun),
m_p_set_fun(p_set_fun), m_p_get_ref_fun(p_get_ref_fun) {}
T& operator =(const_reference_type value) {
(m_p_obj->*m_p_set_fun)(value);
return (m_p_obj->*m_p_get_ref_fun)();
}
operator const_reference_type() {
return (m_p_obj->*m_p_get_fun)();
}
private:
class_type* m_p_obj;
get_type m_p_get_fun;
set_type m_p_set_fun;
get_ref_type m_p_get_ref_fun;
};
class example {
public:
example() : width(this, &example::get_width, &example::set_width,
&example::get_ref_width), title(this, &example::get_title,
&example::set_title, &example::get_ref_title), m_width(0), m_title()
{};
property<example, int, int> width;
property<example, string> title;
private:
int m_width;
int get_width() const {
return m_width;
}
void set_width(int width) {
m_width = width;
}
int& get_ref_width() {
return m_width;
}
string m_title;
const string& get_title() const {
return m_title;
}
void set_title(const string& title) {
m_title = title;
}
string& get_ref_title() {
return m_title;
}
};
void test(int val) {
cout << "test(int): " << val << endl;
}
void test(const string& val) {
cout << "test(string): " << val << endl;
}
int main(int, char* []) {
example ex;
cout << "ex.width: " << static_cast<int>(ex.width) << endl;
cout << "ex.title: " << static_cast<const string&>(ex.title) << endl;
ex.width = 1;
ex.title = "title";
cout << "ex.width: " << static_cast<int>(ex.width) << endl;
cout << "ex.title: " << static_cast<const string&>(ex.title) << endl;
test(ex.width);
test(ex.title);
return 0;
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
The code compiles and workes fine on GCC (however I do not remebrer
which version) and MS VS 2005.
Note that I pass pointer "this" in constructor - which is not a
good idea to do. However this code does not use this value before the
construction completes so no problem - bu if you want to remove this
you can always allow late initialization of this pointer (but then you
would HAVE to remember to do this).
The idea behind this is to make a tamplate class which will allow
property-like behavior. You must pass some arguments as you can read
from the code. const_reference_T is used to allow the behavior with
basic types where you do not use reference but a simple type.
As you can see using to << operator requires explicit cast. You can
remove this by decalring the operator for property class.
Naturally the class can be easly modified to react on other needs
or to simulate get-only or set-only properties. I think that using
template metaprograming could improve the code. This was just a quick
try to give you some ideas.
Adam Badura