Как вы ищете ошибки в программе? - страница 4

 
Konstantin:

а зачем так делать? ведь класс это исходник включаемого файла, зачем класс или его часть вставлять в mq5?

Считаю это очень удобным и правильным, это способствует отделению интерфейсов и реализации.

Во-первых, интерфейс класса получается в отдельном небольшом файле mqh, и тонкости реализации, которые находятся в mq5 его не захламляют.

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

Кроме этого - данный подход позволяет абстраггироваться от различий в МТ4 и МТ5. Пользователь просто объявляет объект CTradePosition:pubic CTradePositionI, вызывает метод Select(), после чего у позиции можно узнать количество компонент, и данные каждой компоненты, с помощью все тех же чисто виртуальных функций. В результате - пользователь вобще никак не касается особенностей платформы - он всегда работает в рамках определенного заранее виртуального интерфейса.

Вот, это самый интерфейс CTradePositionI с чисто виртуальными функциями - также вынесен в отдельный файл. И везде, где он требуется, в заголовке включается именно он.

 
George Merts:

Хотя, у меня каждый класс оформляется в виде пары mqh-mq5, так что даже простые проекты у меня включают более сотни файлов.

У меня один mq5 и классы в одном или более mqh-файлах.
Интересно было бы взглянуть на Ваш проект, не с сотнями файлов, конечно. Или поподробнее схему с более чем одной связкой mqh-mq5. Если есть время, поделитесь, пожалуйста.
 
George Merts:

Считаю это очень удобным и правильным, это способствует отделению интерфейсов и реализации.

Во-первых, интерфейс класса получается в отдельном небольшом файле mqh, и тонкости реализации, которые находятся в mq5 его не захламляют.

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

Кроме этого - данный подход позволяет абстраггироваться от различий в МТ4 и МТ5. Пользователь просто объявляет объект CTradePosition:pubic CTradePositionI, вызывает метод Select(), после чего у позиции можно узнать количество компонент, и данные каждой компоненты, с помощью все тех же чисто виртуальных функций. В результате - пользователь вобще никак не касается особенностей платформы - он всегда работает в рамках определенного заранее виртуального интерфейса.

Вот, это самый интерфейс CTradePositionI с чисто виртуальными функциями - также вынесен в отдельный файл. И везде, где он требуется, в заголовке включается именно он.

вы меня не поняли, классы конечно удобнее разделять на объявление и реализацию, я имею в виду зачем делать два файла из mqh и mq5, ведь mq5 это по сути исполняемый файл исходник, поэтому и не понятно, зачем вставлять часть класса в файл mq5 ))
 
Konstantin:
я имею в виду зачем делать два файла из mqh и mq5, ведь mq5 это по сути исполняемый файл исходник, поэтому и не понятно, зачем вставлять часть класса в файл mq5 ))
незачем. в mql нет модулей компиляции, поэтому смысла в этом ровно ноль.
 
Комбинатор:
незачем. в mql нет модулей компиляции, поэтому смысла в этом ровно ноль.

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

Разумеется, "физически" - разницы никакой. Все равно в компиляцию включается оба файла.

 
Vasiliy Pushkaryov:
У меня один mq5 и классы в одном или более mqh-файлах.
Интересно было бы взглянуть на Ваш проект, не с сотнями файлов, конечно. Или поподробнее схему с более чем одной связкой mqh-mq5. Если есть время, поделитесь, пожалуйста.

Прикрепляю свой переносимый класс CTradeProcessor, построенный на основе виртуального интерфейса CTradeProcessorI -

Для работы - внутри эксперта существует объект CTradeProcessor. Прямо он недоступен, но можно получить указатель на него, в форме  CTradeProcessorI*, который описан в отдельном файле.

Когда требуется, у этого интерфейса вызывается соответствующая виртуальная функция.

Точно по тому же принципу у меня написан класс позиции и менеджера отложенных ордеров, тонкости реализации - перенесены в отдельные файлы, реальный объект существует внутри объекта эксперта, пользователь может получить доступ только к чисто виртуальному интерфейсу позиции или менеджера отложек. 

 
George Merts:

Прикрепляю свой переносимый класс CTradeProcessor, построенный на основе виртуального интерфейса CTradeProcessorI -

Спасибо.
 

Собственно файл эксперта, как я уже и говорил - у меня очень короткий:

#define _FORCETRACE 1
#define _FORCEASSERT 1

#include <MyLib\DebugOrRelease\DebugSupport.mqh>
#include <MyLib\Factories\LSMCanal_EPF.mq5>

DECLARE_MAGIC_NO_INPUT(1234);

// Объявляем фабрику частей эксперта.
CLSMCanal_EPF lcpfFactory(CS_CURRENT_SYMBOL,PERIOD_CURRENT);

// Объявляем функцию получения указателя на фабрику.
CEAPartsFactoryT* CEAPartsFactoryT::GetAdvisorsPartsFactory(uint uiFactoryIdx = 0) { if(uiFactoryIdx == 0) return(GetPointer(lcpfFactory)); return(NULL); };

// Файл шаблона советника
#include <MyLib\TSTemplate\ExpertAdvisorT.mq5>

Вот и весь советник.

Вначале стоят дефайны, управляющие ассертами и трейсами.

Потом подключается библиотека самих трейсов и ассертов.

Далее подключается файл, в котором описан класс фабрики частей эксперта на основе LSM-канала.

Затем объявляем макрос, отвечающий за магик (магик используется и самой фабрикой, и лог-файлом, и трейсами, поэтому нужен специальный макрос, который разворачивается в отдельный объект)

Затем объявляем саму фабрику.

И объявляем функцию, с помощью которой можем получить n-ю фабрику (в эксперте могут быть несколько фабрик, по разным символам)

В конце - подключается шаблон со стандартными функциями, там, в OnInit() вызывается функция получения фабрики, затем у фабрики - запрашиваются все необходимые части эксперта, и если все в порядке - в OnTick - полученные части эксперта начинают работать.

 
Alexey Volchanskiy:

Нужно срочно отлить себя в бронзе ))

Сейчас отливают в граните - умные люди так говорили.

А в бронзе нынче видимо  высекают.

 
Yuriy Zaytsev:

Сейчас отливают в граните - умные люди так говорили.

Это вообще не о том.) Есть и более прозаичная трактовка.
Причина обращения: