Разговоры на завалинке о ООП - страница 5

 
Alexey Volchanskiy:

Прочитал все, какие у всех разные интересы...Я вот сейчас переделываю класс для выставления и управления виртуальной сеткой, мне это надо.

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

 
Dennis Kirichenko:

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

Похоже, пишу очень примитивные вещи...

 
Dennis Kirichenko:
 

Можно использовать указатель на функцию.

Получится ли так с виртуальной функцией-то ?

Да и указатель на функцию - у меня всегда вызывал внутреннее отторжение. Сейчас уже не помню, почему, при работе на "чистом С" - указатели на функции использовались. Но при переходе на С++ от них по какой-то причине пришлось отказаться. И с тех пор - я их не использую.  Указатель - он должен быть на объект.

Но не буду утверждать, что я "прав на все сто". Согласен, что во мне много олдскульного старперского опыта.

 
fxsaber:

Похоже, пишу очень примитивные вещи...

Не скромничай.

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

 
George Merts:


...У меня эта функция выглядит так:

int CFactoryBalanceResultSeries::Compare(const CObject *poNode,const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch(iMode)
      {
      case FSM_BY_PART_OF_MAX_DD_A:    return(_CompareByPartOfMaxDDWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_DD_D:    return(_CompareByPartOfMaxDDWith(pfdsAnother,false));

      case FSM_BY_PART_OF_MAX_SLQUEUE_A: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_SLQUEUE_D: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,false));

      case FSM_BY_LAST_PRCDATA_A:      return(_CompareByLastPrcdataWith(pfdsAnother,true));
      case FSM_BY_LAST_PRCDATA_D:      return(_CompareByLastPrcdataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYDATA_A:      return(_CompareByLastMnydataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYDATA_D:      return(_CompareByLastMnydataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYLOTDATA_A:   return(_CompareByLastMnylotdataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYLOTDATA_D:   return(_CompareByLastMnylotdataWith(pfdsAnother,false));
      
      case FSM_BY_PRCYEARRECOVERY_A:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,true));
      case FSM_BY_PRCYEARRECOVERY_D:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYYEARRECOVERY_A:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYYEARRECOVERY_D:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYLOTYEARRECOVERY_A:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYLOTYEARRECOVERY_D:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,false));
      
      case FSM_BY_PRCVAR_A:            return(_CompareByPrcVarWith(pfdsAnother,true));
      case FSM_BY_PRCVAR_D:            return(_CompareByPrcVarWith(pfdsAnother,false));
      case FSM_BY_MNYVAR_A:            return(_CompareByMnyVarWith(pfdsAnother,true));
      case FSM_BY_MNYVAR_D:            return(_CompareByMnyVarWith(pfdsAnother,false));
      case FSM_BY_MNYLOTVAR_A:         return(_CompareByMnylotVarWith(pfdsAnother,true));
      case FSM_BY_MNYLOTVAR_D:         return(_CompareByMnylotVarWith(pfdsAnother,false));
      
      case FSM_BY_PRC_GRAILRATIO_A:    return(_CompareByPrcGrailratioWith(pfdsAnother,true));
      case FSM_BY_PRC_GRAILRATIO_D:    return(_CompareByPrcGrailratioWith(pfdsAnother,false));

      case FSM_BY_MAGIC_A:             return(_CompareByMagicWith(pfdsAnother,true));
      case FSM_BY_MAIGC_D:             return(_CompareByMagicWith(pfdsAnother,false));
      default:
         break;
      };
         
   return(NULL);
};

George, здесь не видно, например, функция _CompareByPrcVarWith() - метод класса или обычная функция. В С++ есть указатели на методы класса. Там у них своя специфика... Честно, в MQL5 я не пробовал использовать такие указатели.

Но, думаю, что всё же у Вас есть резерв для улучшения структуры кода.

Ведь что такое функция? 

Фу́нкция (лат. functio — «исполнение, совершение; служебная обязанность») — отношение между элементами, в котором изменение в одном влечёт изменение в другом.

Т.е. функция что-то делает. Желательно, чтобы однообразные действия объединялись в теле одной функции.

В Вашем примере очевидно, что функции

_CompareByPartOfMaxDDWith(),

_CompareByPartOfMaxSLQueueWith(),

_CompareByLastPrcdataWith(),

_CompareByLastMnydataWith() и пр.

занимаются СРАВНЕНИЕМ и выдают на-гора  результат этого сравнения. Отличаются именами. Имхо, нехорошая практика. Лучше пускай отличаются параметрами...

Так вот. Думаю, стОит либо слить все функции в одну, либо сделать как виртуальные методы, ну или шаблонные. Ест-но классы должны подчиняться иерархии "родитель-потомок".

Вообще, очень просто написать сложный код, и очень сложно - простой. 

 
Dennis Kirichenko:

George, здесь не видно, например, функция _CompareByPrcVarWith() - метод класса или обычная функция. В С++ есть указатели на методы класса. Там у них своя специфика... Честно, в MQL5 я не пробовал использовать такие указатели.

Это (и все, начинающиеся с подчеркивания) -  протектед-функция класса.

занимаются СРАВНЕНИЕМ и выдают на-гора  результат этого сравнения. Отличаются именами. Имхо, нехорошая практика. Лучше пускай отличаются параметрами...

Так вот. Думаю, стОит либо слить все функции в одну, либо сделать как виртуальные методы, ну или шаблонные. Ест-но классы должны подчиняться иерархии "родитель-потомок".

Дык они ж и слиты в одну !

Функция одна - Compare(), но в ней надо произвести сравнение по передаваемому ключу. Соответственно, выбирается одна из конкретных протектед-функций. Поэтому они и защищенные (протектед), чтобы пользователь не мог к ним обратиться - обращение к ним осуществляется исключительно из Compare(), что и показывает подчеркивание.

Это тоже одно из правил оформления кода - функция, начинающаяся с подчеркивания - не предназначена для вызова пользователями, она обслуживает только определенные внутриклассовые задачи. Доступ к ней - ограничен.

 
Dennis Kirichenko:

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


Денис, я хотел сказать, что у всех разные подходы. Вообще, когда вчера открыл ветку, было интересно посмотреть, появятся ли вчерашние нытики а-ля "а-а-а ООП это очень сложно, СБ - это ужасный черный ящик". Они не появились, чего и следовало ожидать.

Зато прорезались люди и у каждого свой подход. Это тоже интересно в плане общих проектов, о которых так много говорит Ренат.

ЗЫ: общий доступ в проектах так и не работает, недавно пробовал.

 
George Merts:

Это (и все, начинающиеся с подчеркивания) -  протектед-функция класса.

Дык они ж и слиты в одну !

Функция одна - Compare(), но в ней надо произвести сравнение по передаваемому ключу. Соответственно, выбирается одна из конкретных протектед-функций. Поэтому они и защищенные (протектед), чтобы пользователь не мог к ним обратиться - обращение к ним осуществляется исключительно из Compare(), что и показывает подчеркивание.

Это тоже одно из правил оформления кода - функция, начинающаяся с подчеркивания - не предназначена для вызова пользователями, она обслуживает только определенные внутриклассовые задачи. Доступ к ней - ограничен.


Как слиты, если у Вас много методов _CompareXXX() ? А должен быть 1  в моём понимании.

Вопрос, например метод _CompareByPartOfMaxDDWith() вызывается ещё где-нибудь кроме как в CFactoryBalanceResultSeries::Compare() ?

 
Dennis Kirichenko:

Как слиты, если у Вас много методов _CompareXXX() ? А должен быть 1  в моём понимании.

Вопрос, например метод _CompareByPartOfMaxDDWith() вызывается ещё где-нибудь кроме как в CFactoryBalanceResultSeries::Compare() ?

Если метод _СompareXXX() один - то он ничем не отличается от изначальной виртуальной функции Compare().

В том-то и дело, что методы _CompareBy...() - вызываются исключительно из основного Compare(). О чем и предупреждает подчеркивание вначале.

Общий метод Compare() - принимает указатели на два объекта и ключ, указывающий как сравнивать. В этом общем методе анализируется ключ, и после этого - вызывается уже конкретный метод, предназначенный для сравнения исключительно одним ключом. Причем каждый из этих методов вычисляет значение ключей двух переданных объектов, и в зависимости от того, ключ int,double, bool или string - вызывается метод (тоже защищенный) сравнения конкретного типа.

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

 
George Merts:

Если метод _СompareXXX() один - то он ничем не отличается от изначальной виртуальной функции Compare().

В том-то и дело, что методы _CompareBy...() - вызываются исключительно из основного Compare(). О чем и предупреждает подчеркивание вначале.

Общий метод Compare() - принимает указатели на два объекта и ключ, указывающий как сравнивать. В этом общем методе анализируется ключ, и после этого - вызывается уже конкретный метод, предназначенный для сравнения исключительно одним ключом. Причем каждый из этих методов вычисляет значение ключей двух переданных объектов, и в зависимости от того, ключ int,double, bool или string - вызывается метод (тоже защищенный) сравнения конкретного типа.

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


Я Вас понял. Наверное дело вкуса. Но я всё бы сделал в одном методе. Особенно, если защищённые и приватные методы больше нигде не вызываются кроме как в Compare().