Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> "Умная" работа с переменными-членами класса 
:(
    Опции темы
mes
Дата 20.3.2009, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Lazin @  20.3.2009,  17:03 Найти цитируемый пост)
в принципе, так можно добавить любую операцию, зависящую от всех данных сразу, например преобразование координат, в то-же время, можно писать обобщенные версии ф-ий,


Ради одних преимуществ, Вы абсолютно потеряли другие, а ведь ничто не мешало пользоваться и тем и другим.

Начнем с того что Ваш_метод :
1. открывает приватные переменные и разрешает кому угодно что угодно с ними делать.
2. ведет к потери индивидуальности каждого класса
3. и при всем этом не предоставляет разделение операций от субъектов.

Цитата(Lazin @  20.3.2009,  16:47 Найти цитируемый пост)
теперь не обязательно реализовывать метод GenericBody::draw, функторы, занимающиеся отрисовкой фигур можно использовать повторно, либо написать обобщенную версию такого функтора smile  

да использование внешних функций/функторов как прообраз операции это хорошо. Однако Ваш_метод затрудняет написание и поощряет опечатки.. 






--------------------
PM MAIL WWW   Вверх
Lazin
Дата 20.3.2009, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(mes @  20.3.2009,  19:25 Найти цитируемый пост)
1. открывает приватные переменные и разрешает кому угодно что угодно с ними делать.
Согласен, но, я писал этот код наспех, и использовал кругом структуры, тупо ради того, что-бы не писать private, protected, public в самих классах и при наследовании. Ну и поскольку это просто набросок, я не думал о том, какие переменные должны быть закрытыми, а какие нет, я просто сделал все открытым, что-бы мне было проще это все писать.

Цитата(mes @  20.3.2009,  19:25 Найти цитируемый пост)
2. ведет к потери индивидуальности каждого класса

Что под этим имеется ввиду? Да, все классы будут сгенерированы компилятором,  то как они бдут работать можно настроить. А можно просто отнаследовать свой класс от Body, и сделать их него настоящую индивидуальность smile 

Цитата(mes @  20.3.2009,  19:25 Найти цитируемый пост)
3. и при всем этом не предоставляет разделение операций от субъектов

Совсем не сложно сделать метод draw - функцией, или реализовать тот-же самый паттерн visitor, но только для всего объекта, а не для его частей.

Цитата(mes @  20.3.2009,  19:25 Найти цитируемый пост)
Ради одних преимуществ, Вы абсолютно потеряли другие, а ведь ничто не мешало пользоваться и тем и другим

привиди пример, как бы ты это сделал, может я чего-то не понимаю...?
PM MAIL Skype GTalk   Вверх
mes
Дата 20.3.2009, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Lazin @  20.3.2009,  19:09 Найти цитируемый пост)
но, я писал этот код наспех, и использовал кругом структуры, тупо ради того, что-бы не писать private, protected, public в самих классах и при наследовании. Ну и поскольку это просто набросок, я не думал о том, какие переменные должны быть закрытыми, а какие нет, я просто сделал все открытым, что-бы мне было проще это все писать.

нее... Я не о том, что все через public написано.. это понятно что демонстрационное, а о том что все функции оперируют внутренним состоянием фигуры


Цитата(Lazin @  20.3.2009,  19:09 Найти цитируемый пост)
привиди пример, как бы ты это сделал, может я чего-то не понимаю...? 

вобщем возмущения 
 из за typedef :

Цитата(Lazin @  20.3.2009,  16:16 Найти цитируемый пост)
typedef GenericBody< boost::fusion::vector<point, point> > Line;


из за пользования приватными знаниями :
Цитата(Lazin @  20.3.2009,  16:47 Найти цитируемый пост)
struct DrawLine
{
    void operator()(DrawContext& dc, const line_sequence_type& line)
    {
        dc.MoveTo(boost::fusion::at_c<0>(line));


опять из за typedef, что приведет к затруднению перегрузки:
Цитата(Lazin @  20.3.2009,  16:47 Найти цитируемый пост)
typedef boost::fusion::vector<point, point>  line_sequence_type;


ну и конечно BodyAccessor в качестве запроса характеристик от пользователя, как из за  доступа к приватным данным, так и из заограничений возможностей запроса.
например Circle всегда будет запрашиваться как точка и и длина, а не как центр и радиус, не говоря о том, что не возможно задать двумя точками.

Цитата(Lazin @  20.3.2009,  13:33 Найти цитируемый пост)
struct InputAccessor : BodyAccessor
{
    void operator () (const metadata& p) const
    {
        std::cout << "Input params for " << p.class_name << std::endl;
    }



Цитата(Lazin @  20.3.2009,  19:09 Найти цитируемый пост)
привиди пример, как бы ты это сделал, может я чего-то не понимаю...? 


оставить возможности Body только для сериализации и ей подобной.
получать типы фигур не typedef, a наследованием.
тайпдефить fusion::vector внутри класса фигуры, которой он принадлежит
и разгружать ее данные через функции.

т.е так 
Код

class FCircle : public Figure
{
        typedef  boost::fusion::vector<point, length> data_t;
       data_t   m_data;
  public:
      int Radius () { return ..at_c<1>(m_data); }
      int Center () { return ..at_c<0>(m_data); }
      void Draw (.. dc) { dc.DrawCircle (Center(), Radius()); }
};


ну а Inputer может быть привязан не к самим фигурам , а к их составляющем; но без допуска к внутренностям объекта.
например так:
Код

struct Inputer
{
   virtual void Аcquaint (metadata&) =0;
   virtual int GetRadus () =0;
   virtual int GetLength()=0;
   virtual int GetCenter()=0;
};

struct ConsoleInputer : Inputer
{
    virtual void Аcquaint (metadata& data)  { cout<< "Enter data for " << data.name()<<endl; }
   virtual int GetRadus ()  { int rad: cout <<"Radius : " ; cin >>rad; return rad; } ;
   virtual int GetLength()  {..};
  ..
}



Это сообщение отредактировал(а) mes - 20.3.2009, 21:37


--------------------
PM MAIL WWW   Вверх
Lazin
Дата 22.3.2009, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



я немного поковырял этот код, улучшил его, но не так как говорил mes smile 
в общем, я вынес всю шаблонную магию в отдельный класс, от которого можно наследовать
ф-ии DrawCircle, и DrawLine, теперь не получают ссылку на sequence, вместо этого они принимают обычный набор параметров, пользователь теперь может писать такие функции:
Код

struct DrawLine
{
    void operator()(const DrawContext& dc, const point& begin, const point& end)
    {
        std::cout << "DrawLine" << std::endl;
        dc.MoveTo(begin);
        dc.LineTo(end);
    }
};

получать переменные класса можно так-же как и у boost::fusion::vector, с помощью at_c
класс GenericBody теперь выглядит намного проще
Код

template<class Sequence, class DrawFn>
struct GenericShape : Shape, composite_object<Sequence>
{
    const metadata &traits;
    typedef Sequence param_type;

    GenericShape( const Sequence& s, const metadata& m )
        : composite_object<Sequence>(s)
        , traits(m)
    {
    }

    virtual void access(const BodyAccessor& a)
    {
        a(traits);
        this->for_each(a);
    }

    virtual void draw(DrawContext& dc)
    {
        DrawFn fn;
        this->apply(fn, dc);
    }
};

весь код я решил не выкладывать, вместо этого, код можно получить из моего репозитория на bitbucket - composite_object

Добавлено через 3 минуты и 17 секунд
ps
еще можно сделать так, что-бы конструктор composite_object-a принимал не ForwardSequence, а обычный набор параметров, а потом запаковывал его в последовательность
в идеале, пользователь класса не дожен вообще уметь пользоваться boost::fusion
PM MAIL Skype GTalk   Вверх
mes
Дата 22.3.2009, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Lazin @  21.3.2009,  23:19 Найти цитируемый пост)
ф-ии DrawCircle, и DrawLine, теперь не получают ссылку на sequence, вместо этого они принимают обычный набор параметров, пользователь теперь может писать такие функции:

ага , к самим структурам претензий нет, однако  порядок парамeтров все равно жестко прописан на sequence. 
т.е если вдруг функции нужен только один параметр, она все равно должна иметь в определении всю  очередность.


Цитата(Lazin @  21.3.2009,  23:19 Найти цитируемый пост)
вынес всю шаблонную магию в отдельный класс, 

в шаблонной магии тоже ничего не режет глаз, однако main.cc все так же и остался полон зависимостей и ограничений.
(не буду повторяться какие, потому что основные замечания описаны в предыдущем посте) smile

Это сообщение отредактировал(а) mes - 22.3.2009, 00:55


--------------------
PM MAIL WWW   Вверх
Lazin
Дата 22.3.2009, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(mes @  22.3.2009,  00:52 Найти цитируемый пост)
main.cc все так же и остался полон зависимостей и ограничений.

эти ограничения не на пустом месте появились, за все нужно платить
в принципе, можно порождать новые классы с помощью наследования, а не typedef 
Код

struct Rect : Shape, composite_object< boost::fusion::vector< point, point > >
{
    const metadata& traits;
    Rect(const point& p1, const point& p2, const metadata& m) 
        : composite_object<boost::fusion::vector<point, point> >( boost::fusion::make_vector(p1, p2) )
        , traits(m)
    {
    }

    point& first()
    {
        return at_c<0>(*this);
    }

    point& second()
    {
        return at_c<1>(*this);
    }

    virtual void access(const BodyAccessor& a)
    {
        a(traits);
        this->for_each(a);
    }
    virtual void draw(DrawContext& dc)
    {
        dc.DrawRect(first(), second());
    }
};

но писанины больше...

Цитата(mes @  20.3.2009,  21:32 Найти цитируемый пост)
получать типы фигур не typedef, a наследованием

я не вижу каких-либо проблемм с typedef smile 
Цитата(mes @  22.3.2009,  00:52 Найти цитируемый пост)
однако  порядок парамeтров все равно жестко прописан на sequence. 
т.е если вдруг функции нужен только один параметр, она все равно должна иметь в определении всю  очередность.

можно поступить так, как в предидущем примере, но степень обобщенности в этом случае ниже... придется многие ф-ии писать ручками, т.е один класс, одна ф-я, и нельзя их комбинировать... 
в случае, если потомков Shape/Body очень много, это может быть не так удобно.. с другой стороны передача нескольких лишних параметров по ссылке, вряд-ли вызовает проблеммы с производительностью, так-что, я думаю что все ок...

Добавлено через 33 секунды
зы
обновил код в репозитории, хотя изменений там мало
PM MAIL Skype GTalk   Вверх
mes
Дата 22.3.2009, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Lazin @  22.3.2009,  13:21 Найти цитируемый пост)
с другой стороны передача нескольких лишних параметров по ссылке, вряд-ли вызовает проблеммы с производительностью, так-что, я думаю что все ок...

о производительности тут речи не шло smile шло лишь об удобстве пользователя.


Цитата(Lazin @  22.3.2009,  13:21 Найти цитируемый пост)
ожно поступить так, как в предидущем примере, но степень обобщенности в этом случае ниже... придется многие ф-ии писать ручками, т.е один класс, одна ф-я, и нельзя их комбинировать...

Наш спор в основном вызван тем, что Ваш_метод мы рассматриваем применительно к иерархии фигур. 
Дело в том что у примитивов фигур очень мало действительно общего, и обобщение на уровне их состояния (приватных данных) только вызывает путаницу.

Цитата(Lazin @  22.3.2009,  13:21 Найти цитируемый пост)
придется многие ф-ии писать ручками, т.е один класс, одна ф-я, и нельзя их комбинировать...

да каркас класса придется писать ручками, но лично я считаю это, применительно к выше-обсуждаемой задаче, преимуществом.
Очень неудобно работать с одним и тем же интерфейсом с Линией, Углом, Трапецией и Кубом. 
Но это не мешает нам комбинировать их функции. Для этого достаточно разбить на двa условных уровня :
 функции/функторы и классы их использующее (как в принципе у Вас и обстоит дела с рисованием)


Цитата(Lazin @  22.3.2009,  13:21 Найти цитируемый пост)

я не вижу каких-либо проблемм с typedef smile 

проблема не с typedef,  а с абсолютной унификацией (потерей индивидуальности) интерфейса (опять же оговорюсж, что лишь применительно к нашей задаче)

Цитата(Lazin @  22.3.2009,  13:21 Найти цитируемый пост)

эти ограничения не на пустом месте появились, за все нужно платить

ну а как иначе.. просто из двух зол выбирают меньшее smile

и еще раз замечу, что основное замечание, было к InputAccessor`у, ради которого в принципе и была применена технология комбинирования.

Добавлено через 5 минут и 8 секунд
Цитата(Lazin @  20.3.2009,  17:03 Найти цитируемый пост)
Что-бы написать, к примеру, ф-ю считающую количество вершин геом. фигуры, нужно написать всего один функтор. 

Как понял с помощью BodyAccessora ? ну и что вернет Ваш функтор применительно к окружности ?! ;)


--------------------
PM MAIL WWW   Вверх
Lazin
Дата 22.3.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(mes @  22.3.2009,  14:44 Найти цитируемый пост)
Как понял с помощью BodyAccessora ? ну и что вернет Ваш функтор применительно к окружности ?! ;) 

это просто не удачный пример, вот и все
Цитата(mes @  22.3.2009,  14:44 Найти цитируемый пост)
и еще раз замечу, что основное замечание, было к InputAccessor`у, ради которого в принципе и была применена технология комбинирования.

ну, смотря для чего его использовать, если для сериализации, и подобных сериализации задач, то проблемм нет, для более интелектуальных задач это использовать уже сложнее
можно организовать что-то вроде двойной диспетчеризации, передавать в BodyAccessor, не только параметры, но и ссылку на сам объект, в этом случае можно будет перегрузить операции для разных объектов
PM MAIL Skype GTalk   Вверх
mes
Дата 22.3.2009, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Lazin @  22.3.2009,  14:54 Найти цитируемый пост)
ну, смотря для чего его использовать, если для сериализации, и подобных сериализации задач, то проблемм нет,

Цитата(mes @  20.3.2009,  20:32 Найти цитируемый пост)
оставить возможности Body только для сериализации и ей подобной.

smile

Цитата(Lazin @  22.3.2009,  14:54 Найти цитируемый пост)
для более интелектуальных задач это использовать уже сложнее
можно организовать что-то вроде двойной диспетчеризации, передавать в BodyAccessor, не только параметры, но и ссылку на сам объект, в этом случае можно будет перегрузить операции для разных объектов 

зачем усложнять, когда стандартным подходом это решается нагляднее и проще. smile

ну а  в общем мне кажется, что мы уже в принципе пришли к "общему знаменателю" по этой ветке темы
smile


Это сообщение отредактировал(а) mes - 22.3.2009, 16:51


--------------------
PM MAIL WWW   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0953 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.