Здравствуйте, Erop, Вы писали:
P>>это как? какой синтаксис получится? P>>"object.some_property=some_shit" ? E>Да, почему нет? Просто класс описывать будет неудобно.
не, я спрашивал как именно такое реализуется наследованием.
Здравствуйте, Piko, Вы писали:
P>не, я спрашивал как именно такое реализуется наследованием.
Вопроса не понял. По графу наследования в С++ можно ходить вполне легально
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
P>>не, я спрашивал как именно такое реализуется наследованием. E>Вопроса не понял. По графу наследования в С++ можно ходить вполне легально
Как вот это "object.some_property=some_shit" реализуется через наследование, да причём так, чтобы some_property имело доступ к object ?
Здравствуйте, Piko, Вы писали:
P>Как вот это "object.some_property=some_shit" реализуется через наследование, да причём так, чтобы some_property имело доступ к object ?
Через CRTP, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Piko, Вы писали:
P>Как вот это "object.some_property=some_shit" реализуется через наследование, да причём так, чтобы some_property имело доступ к object ?
template<typename THost, typename T, typename Tag = void>
class CppProperty {
T data;
protected:
CppProperty() : data( T() ) {}
// конструкторы копии дефолтныйvirtual void OnChange( CppProperty* = 0 ) { } // тут можно бы и избавиться от виртуальности.
// например, в методах CppProperty дёргать что-то вроде Host().OnChange(), но это менее банально.
THost& Host() { return *static_cast<THost*>( this ); }// тут мы требуем или дружбы или публичного наследованияconst THost& Host() const { return *static_cast<const THost*>( this ); }// тут тожеpublic:
CppProperty( const T& d ) : data( d ) {}
void operator = ( const CppProperty& d ) { data = d.data; OnChange(); }
void operator = ( const T& d ) { data = d; OnChange(); }
operator const T&() const { return data; }
CppProperty operator + ( const T& right ) const;
CppProperty operator + ( const CppProperty& right ) const;
CppProperty& operator += ( const T& right );
CppProperty& operator += ( const CppProperty& right );
// далее по аналогии для всех Срр операторов
};
template<typename THost, typename T, typename Tag>
inline CppProperty<THost, T, Tag> CppProperty<THost, T, Tag>::operator + ( const T& right ) const
{
return data + right;
}
template<typename THost, typename T, typename Tag>
CppProperty<THost, T, Tag> CppProperty<THost, T, Tag>::operator + ( const CppProperty<THost, T, Tag>& right ) const
{
return data + right.data;
}
template<typename THost, typename T, typename Tag>
inline CppProperty<THost, T, Tag> operator + ( const T& left, const CppProperty<THost, T, Tag>& right )
{
CppProperty<THost, T, Tag> res( left );
res += right;
return res;
}
template<typename THost, typename T, typename Tag>
inline CppProperty<THost, T, Tag>& CppProperty<THost, T, Tag>::operator += ( const T& right )
{
data += right;
OnChange();
return *this;
}
template<typename THost, typename T, typename Tag>
CppProperty<THost, T, Tag>& CppProperty<THost, T, Tag>::operator += ( const CppProperty<THost, T, Tag>& right )
{
data += right.data;
OnChange();
return *this;
}
// далее по аналогии
//------------------------------class MyClass : CppProperty<MyClass, int> {
public:
CppProperty<MyClass, int>& MyProp;
MyClass() : MyProp( *this ), count( 0 ) {}
MyClass( const MyClass& other ) : CppProperty<MyClass, int>( other ), MyProp( *this ), count( 0 ) {}
int ChangeCount() const { return count; }
protected:
int count;
virtual void OnChange( CppProperty<MyClass, int>* ) { count++; }
};
int foo_oo( int ii )
{
MyClass m;
m.MyProp = ii;
m.MyProp += 10;
m.MyProp += m.MyProp;
int count = m.ChangeCount();
return count;
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
P>>Как вот это "object.some_property=some_shit" реализуется через наследование, да причём так, чтобы some_property имело доступ к object ? E>Через CRTP, например...
как СRTP поможет объекту some_property иметь доступ к объекту object?
Здравствуйте, Piko, Вы писали:
P>>>Как вот это "object.some_property=some_shit" реализуется через наследование, да причём так, чтобы some_property имело доступ к object ? E>>Через CRTP, например... P>как СRTP поможет объекту some_property иметь доступ к объекту object?
Здравствуйте, Erop, Вы писали:
P>>>это как? какой синтаксис получится? P>>>"object.some_property=some_shit" ? E>>Да, почему нет? Просто класс описывать будет неудобно. P>не, я спрашивал как именно такое реализуется наследованием.
class MyClass : AsProperty<int> {
вы в том примере это мест имели в виду когда говорили про наследование.
а я подумал может вы знаете способ через наследование, но без ссылок (чтобы без надежды на то, что ссылка соптимизируются).
в любом случае спасибо за пример
Здравствуйте, Mystic, Вы писали:
F>>Это случилось чуть раньше — в OLE/COM. F>>Там надо было. F>>А на них уже соорудили Дельфу.
M>Свойства были еще в Delphi первой версии (16-битная Windows), когда никакой другой языковой поддержки OLE/COM не было.
Св-ва в COM IDL были еще в 90-м году. Так что эту идею дельфя содрало у OLE и VB.
Здравствуйте, jazzer, Вы писали:
J>Ага, пока не попытаешься повесить проверки типа один параметр должен быть больше другого и какой-нть пересчет по изменению. J>Все такие вещи лучше иметь прописанными явно, а не быть закопанными где-то в сеттерах.
Дело не в этом, а в том, что какой-нить функциональный биндинг на ф-ию-сеттер более естественный, чем на переменную.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, jazzer, Вы писали:
J>>Ага, пока не попытаешься повесить проверки типа один параметр должен быть больше другого и какой-нть пересчет по изменению. J>>Все такие вещи лучше иметь прописанными явно, а не быть закопанными где-то в сеттерах.
V>Дело не в этом, а в том, что какой-нить функциональный биндинг на ф-ию-сеттер более естественный, чем на переменную.
Здравствуйте, Piko, Вы писали:
P>а я подумал может вы знаете способ через наследование, но без ссылок (чтобы без надежды на то, что ссылка соптимизируются).
Ну какая разница хранить указатель на хост или на свойство? Оверхед тот же, а хранить удобнее.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
P>>а я подумал может вы знаете способ через наследование, но без ссылок (чтобы без надежды на то, что ссылка соптимизируются). E>Ну какая разница хранить указатель на хост или на свойство? Оверхед тот же, а хранить удобнее.
ну так тут пытались использовать offset of как раз для того, чтобы вообще не хранить указатель, без оверхеда
я подумал может у вас есть какое-то решение без оверхеда через "наследование", поэтому и спросил.
Здравствуйте, Piko, Вы писали:
P>ну так тут пытались использовать offset of как раз для того, чтобы вообще не хранить указатель, без оверхеда
Беда тут в том, что offsetof требует от объемлющего класса быть POD...
P>я подумал может у вас есть какое-то решение без оверхеда через "наследование", поэтому и спросил.
На самом деле, я думаю, что можно так всё устроить, что будет почти без оверхеда.
Но не понятно что за фичи требуются от "пропертей"
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
P>>ну так тут пытались использовать offset of как раз для того, чтобы вообще не хранить указатель, без оверхеда E>Беда тут в том, что offsetof требует от объемлющего класса быть POD...
так я понял это, поэтому и искал другие решения типа разницы двух this.
см. контекстом разговора
P>>я подумал может у вас есть какое-то решение без оверхеда через "наследование", поэтому и спросил. E>На самом деле, я думаю, что можно так всё устроить, что будет почти без оверхеда. E>Но не понятно что за фичи требуются от "пропертей"
я думаю основные фичи:
1. object.propery=someshit
2. someshit=object.property
3. воздействие на агрегирующий объект
1 и 2, достигаются тривиально и без оверхеда.
для 3 я пока не увидел решений без оверхеда.
может любители пропертей хотят ещё что-нибудь.
мне проперти особо не нужны, мне просто интересно как их можно реализовать на C++
Здравствуйте, Piko, Вы писали:
P>я думаю основные фичи: P>1. object.propery=someshit P>2. someshit=object.property P>3. воздействие на агрегирующий объект
P>1 и 2, достигаются тривиально и без оверхеда.
И без пропертей тоже
P>для 3 я пока не увидел решений без оверхеда.
мне так кажется, что в тех местах, где популярны проперти, оверхед не важен
Но, зато, важна возможность ничего не забыть сделать. Типа надо во всех конструкторах связать проперти с this, а это лишает идею посделднего смысла.
P>может любители пропертей хотят ещё что-нибудь. P>мне проперти особо не нужны, мне просто интересно как их можно реализовать на C++
OnChange типа поддержать?
Просто проперти -- они же по бедности в своё время возникли. В Срр хочется, что бы не толко гет и сет можно было дёрнуть, но и += там всякое, или Length() позвать...
Или профильтровать как-то методы оборачиваемого класса.
Вот, скажем, я делаю пропертю из std::vector<xxx> и хотел бы с этой пропертёй работать, как с массивом.
Или, хотя бы, примерно так...
А что касается обеспечения связи объемлющего объекта и вложенного, то там много решений возможно, в разной степени чистых.
например, можно взять какой-то нормальнй срр класс без пропертей. Пусть это будет class MyClass
объявить ему другом или вложенным класс MyClass::PropertiesPad.
Этот самый MyClass::PropertiesPad -- POD, и все его плоя -- шаблонные POD'ы без полей и конструкторов, которые в параметре шаблона получают указатель на поле MyClass, или указатель на сеттер и геттер.
Всё через прокчи и приведения типов транслирует в обращения к этой, указуемой переменной.
А адрес своего пала получают через offsetof.
Потом мы из MyClass и MyClass::PropertiesPad выводимся и получаем класс, в котором есть проперти.
При этом MyClass::PropertiesPad не содержит никаких атомарных полей, только пустые POD-стрыктуры.
По идее у компилятора большие возможности по оптимизации
Только не интересно это всё. Намного прикльнее таки с операторами разобраться.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
P>>я думаю основные фичи: P>>1. object.propery=someshit P>>2. someshit=object.property P>>3. воздействие на агрегирующий объект
P>>1 и 2, достигаются тривиально и без оверхеда. E>И без пропертей тоже
да, само собой. value semantic рулит
P>>для 3 я пока не увидел решений без оверхеда. E>мне так кажется, что в тех местах, где популярны проперти, оверхед не важен
да, абсолютно согласен. мне просто интересны без-оверхедные решения
E>Но, зато, важна возможность ничего не забыть сделать. Типа надо во всех конструкторах связать проперти с this, а это лишает идею посделднего смысла.
можно использовать трюк с разным определением макросов (несколько разных определений одного и того же макроса. нужное определение используется по необходимости). это будет более single point of truth
E>А что касается обеспечения связи объемлющего объекта и вложенного, то там много решений возможно, в разной степени чистых.
E>например, можно взять какой-то нормальнй срр класс без пропертей. Пусть это будет class MyClass E>объявить ему другом или вложенным класс MyClass::PropertiesPad. E>Этот самый MyClass::PropertiesPad -- POD, и все его плоя -- шаблонные POD'ы без полей и конструкторов, которые в параметре шаблона получают указатель на поле MyClass, или указатель на сеттер и геттер. E>Всё через прокчи и приведения типов транслирует в обращения к этой, указуемой переменной. E>А адрес своего пала получают через offsetof. E>Потом мы из MyClass и MyClass::PropertiesPad выводимся и получаем класс, в котором есть проперти. E> ...
да, я думал об этом. раз offeset of только для pod — то можно использовать pod обвёртку.
Здравствуйте, Vamp, Вы писали:
J>>эти рекламируемые сайд-эффекты я видел полраза в жизни на тысячи раз, когда я видел пустые сеттеры-геттеры безо всяких сайд-эффектов. V>Я надеялся на твою поддержку!
Мою поддержку лови тоже.
По моему мнению просто ктото давно сказал, что все данные должны быть приватными — дальше остальные
подхватили — и понеслось ... в частности об этом же недавно читал в "священные знания С++"
... напоминает ситуацию с goto
Здравствуйте, carpenter, Вы писали:
C>По моему мнению просто ктото давно сказал, что все данные должны быть приватными — дальше остальные C>подхватили — и понеслось ... в частности об этом же недавно читал в "священные знания С++"
Вообще-то бывают же и просто структуры. std::pair, например...
Это какие-то фанаты безкомпромисные так сказали, наверное. Или в коде-стайле для каких-то совсем упоротых кодеров написали так, потому, что иначе никак
только не понятно при чём тут subj. Публичное у тебя поле или приватное, зачем ему быть пропертёй?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском