пятница, 27 июля 2007 г.

C++ property

Иногда встречается следующая ситуация:

Если такая штуковина часто встречается в коде, можно заюзать такой класс:

И тогда получим:

добавленно позже...
Ссылки на различные реализации свойств (нашол тут):
Properties in C++
«Свойства» в классах C++

6 комментариев:

spk комментирует...

да. токо смысл аксесоров при этом теряется. например, ты легко можешь изменить данные:

A a;
a.a = opt < int >;

то ли дело:

struct A : opt < int >;
{
};

но теперь теряется ООПшность :)

Alexander комментирует...

Смысл в том, что тебе для добавления свойства вместо 3-х строк достаточно дописать одну. А присваивание a.a = opt < int >; просто обнуляет свойство. С таким же успехом можно вызвать a.a.set(0);

Вот наследование тут не катит, т.к. наследоваться придётся для каждого проперти :)

Alexander комментирует...

Ну или добавляет приватный оператор копирования :)

template < class T >
class opt
{
T m_t;
void operator=(const opt& t)
{
m_t = t.m_t;
}
public:
void get(T& t) {t=m_t;}
void set(const T& t) {m_t=t;}
};

spk комментирует...

>Смысл в том, что тебе для добавления свойства вместо 3-х строк достаточно дописать одну.

тогда уж лучше заюзать макросы :) а еще лучше иметь фичу в ИДЕ, которая б из обычного поля делала пропертиз и наоборот..

просто я слабо понимаю где это можно использовать. когда выносишь пропертиз в СОМ?

sash_ko комментирует...

Чем макросы лучше? Если не учитывать все минусы макросов, то код просто станет нечитабельным.

Когда выносишь пропертиз в COM ты описываеш их в idl как пропертиз и реазизуется потом через set/get, так что в случае с СОМ описанный способ не поможет.

А использовать свойство можно для упрощения кода. Если есть несколько членов класса доступ к которым осуществляется через set/get, то удобнее это сделать через свойства. Реальный пример, где можно было бы применить свойства - MFC. Там такого добра навалом.

Мало того, opt - это только минимальная функциональность для свойств. Ведь можно определить оператор присваивания:

template< class T >
class opt
{
    T m_t;
public:
    void operator=(const T& t)
    {
       m_t = t;
    }
};

И тогда юзать свойства можно ещё проще:

A a;
a.a = 50;

Далее, если тебе нужно при установке/получения значения выполнять какие-то действия - можно добавить события.

sash_ko комментирует...

С учётом всех пожеланий, класс opt можно расширить :)

template< class T >
class opt_ex
{
    T m_t;

    void operator=(const opt_ex& opt)
    {
       m_t = opt.m_t;
    }
public:
    void set(const T& t) {m_t=t;}
    void get(T& t) {t=m_t;}
    void operator=(const T& t) {m_t=t;}
};