Re: C++ Templates - passing a pointer to the member to that member's base class
On 4/20/07 10:27 AM, in article
1177080733.878314.49360@n59g2000hsh.googlegroups.com,
"jonas.andero@hotmail.com" <jonas.andero@hotmail.com> wrote:
I'm writing a little framework for interface programming, where the
interfaces are represented by template classes with modern features
like properties ? la C#. While these properties are member variables
with Get and Set operations, it is the implementing class that shall
handle these calls and hence I want Get and Set to be members of the
class that implements the interface.
The folowing code is an example what I want to achive (simplfied).
First the interface class and then an example with a class that
declares a property "time_pos".
-------------- Begin code --------------
template <class C>
class Interface
{
public:
template <class T, class D, D C::* pmp>
class Property
{
public:
typedef typename Property<T, D, pmp> P;
typedef P C::* prop_mbr_ptr;
void Set(T t)
{
C * c = (C*)(((char*)this) - ((char*) &(((C*)0)->*pmp)));
((C &) *this).Set<D, T>(t);
};
T Get() const
{
C * c = (C*)(((char*)this) - ((char*) &(((C*)0)->*pmp)));
return ((C &) *this).Get<D, T>();
};
};
};
Is there a reason why the Property class template cannot store the value of
the property as well? I find the current design - that effectively splits a
single property of the class between two data members (one stores the value
and the other mediates access) - overly complicated. Whereas consolidating
the two data members into one has the advantage of a cleaner design and
implementation:
template <class T>
class Property
{
T prop;
public:
Property() : prop() {}
void Set(const T& t)
{
prop = t;
}
T Get() const
{
return prop;
}
T operator()() const
{
return Get();
}
Property& operator=(const T&t )
{
Set(t);
return *this;
}
};
class Implementation : public Interface<Implementation>
{
public:
// Accessor templates (must be declared!)
template<class P, class T> void Set(T);
template<class P, class T> T Get();
private:
// the Value of the property is kept here
int _time_pos;
public:
// time_pos, a Property of int-type
class time_pos_t : public Property<int, time_pos_t,
&Implementation::time_pos> {} time_pos;
// Specializations of the accessor templates for time_pos
template<> void Set<time_pos_t, int>(int i)
{
_time_pos = i;
}
template<>int Get<time_pos_t, int>()
{
return _time_pos;
}
};
The Implementation class can now be simplified as well:
class Implementation
{
public:
// time_pos, a Property of int-type
Property<int> time_pos;
};
void main()
{
Implementation impl;
impl.time_pos.Set(42);
int i = impl.time_pos.Get();
}
The Property class supports not only explicit Get() and Set() accessors, but
also the assignment and function call operators for a more compact syntax:
int main()
{
Implementation impl;
int i = impl.time_pos.Get();
impl.time_pos.Set(42);
i = impl.time_pos(); // Get() is optional
impl.time_pos = 42; // Set() is optional
}
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]