Вот попробовал написать код поддержки так называемых свойств (как в C#).
Есть замечания и предложения по дизайну или ссылки на уже существующие реализации?
использование:
class Temp
{
public:
Temp(): Length(this, getLength, setLength), len(0) {}
Property<Temp, float, PropertyType::GetSet> Length;
private:
float getLength() const { std::cout << "get called\n"; return len; }
void setLength(float newLength) { std::cout << "set called\n"; len = newLength;}
float len;
};
int main()
{
Temp t;
t.Length = t.Length+2;
std::cout << t.Length;
}
реализация:
#pragma once
namespace PropertyType { enum Type{ Get, Set, GetSet }; };
template <class Class, typename T, PropertyType::Type> class Property;
template <class Class, typename T>
class Property<Class, T, PropertyType::Get>
{
protected:
typedef typename T (Class::*GetFunc)(void) const;
public:
Property(Class* ptr, GetFunc g): obj_ptr(ptr), get(g) {}
operator typename T() const { return (obj_ptr->*get)(); }
private:
Class* obj_ptr;
GetFunc get;
};
template <class Class, typename T>
class Property<Class, T, PropertyType::Set>
{
protected:
typedef void (Class::*SetFunc)(typename T);
public:
Property(Class* ptr, SetFunc s): obj_ptr(ptr), set(s) {}
Property& operator=(const T& value)
{
(obj_ptr->*set)(value);
return *this;
}
private:
Class* obj_ptr;
SetFunc set;
};
template <class Class, typename T>
class Property<Class, T, PropertyType::GetSet>:
public Property<Class, T, PropertyType::Get>, public Property<Class, T, PropertyType::Set>
{
typedef Property<Class, T, PropertyType::Get> BaseGet;
typedef Property<Class, T, PropertyType::Set> BaseSet;
public:
Property(Class* ptr, GetFunc g, SetFunc s): BaseGet(ptr, g), BaseSet(ptr, s) {}
Property& operator=(const T& value)
{
BaseSet::operator=(value);
return *this;
}
};
Мои собственные замечания:
использование:
1) при использовании парит писать имя класса, которому свойство принадлежит
2) использование this в списке инициализации конструктора не безопасно.
реализация:
1) при множественном наследовании объект GetSet занимает 16 байт вместо положенных 12.
2) operator= не наследуется, поэтому приходится писать дублирующий код в GetSet