Property на C++ без расширений языка
От: Undead  
Дата: 15.10.04 19:40
Оценка: :)
Вот попробовал написать код поддержки так называемых свойств (как в 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.