Ошибки, баги, вопросы - страница 3599
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
От буфферизации таймсерий отказались (которая была в четверке)
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Новая версия платформы MetaTrader 5 build 3620: улучшения веб-терминала, поддержка ONNX и ускоренное умножение матриц в MQL5
Renat Fatkhullin, 2023.03.08 16:41
В четверке на самом деле сам терминал для каждого эксперта создает и обновляет фоновую копию/снапшот текущего чарта, чтобы робот потом мог по ней бегать без блокировок.
Преставьте себе, что перед вызовом OnTick происходит CopyRates всей истории в фоновой буфер робота. Конечно, с массой трюков для ускорения. В любом случае, это затратно по памяти и достаточно дорого. Обновление буфера добавляет латенси у реакции на OnTick.
Так как эти фоновые затраты идут вне контекста выполнения робота на MQL4, вам кажется, что скорость внутри MQL4 высока и бесплатна. Но удар по памяти и CPU все равно остается из-за расходов на фоновой буфер.
Причем учтите, то копируется только текущий чарт, что позволяет достаточно быстро работать iOpen/iHigh/iLow/iClose функциям на своем чарте. А вот доступ к другим таймфреймам и символам уже через Copy семантику, что выливается в синхронизированный доступ к базе истории как в пятерке.
Пятерка в этом отношении более честна и экономна:
для быстрого и без поддержания активности на других рабочих периодах, можно использовать индикатор шпион
Точно не знаю, о каком шпионе вы говорите, но для поддержания активности графика достаточно и холостого запроса
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Новая версия платформы MetaTrader 5 build 3620: улучшения веб-терминала, поддержка ONNX и ускоренное умножение матриц в MQL5
Renat Fatkhullin, 2023.03.08 19:00
Тогда с каждым тиком буду запрашивать 1 элемент графика. Для того, чтобы терминал продолжал обновлять этот график. Это позволит всегда получать данные без лишних задержек и приключений. Наверное...😄
(речь идет о "чужом" графике)
Если хотите поддерживать активность таймфрейма, то холостой запрос данных это обеспечит.
Точно не знаю, о каком шпионе вы говорите, но для поддержания активности графика достаточно и холостого запроса
в поиске есть,
Терминал работает экономно, сохраняет данные только открытого графика, а индикатор-шпион будет на всех нужных работать
найти через поиск можно
Правильно ли я понимаю, что спецификатор delete нет смысла использовать, если может быть использована ссылка/указатель на базовый класс? Или в таких случаях необходимо закрытое наследование?
Интересный пример ))
Насколько понимаю, компилятор видит, что в качестве параметра ему передали class Foo & { ... }, но при вызове ::method() всё равно обращается к методу родительского класса, как к единственному разрешённому методу. Что неудивительно, с одной стороны. С другой, как бы легально обходим запрет, созданный с помощью delete. Получается, что спецификатор delete работает только при явном указании типа. Т.е. вот так уже не получится:
void f(Foo &b) { b.method(); }Ошибка: attempting to reference deleted function 'void Foo::method()'
Таким образом, в первом случае, когда параметр Base, мы сталкиваемся, я бы сказал, с лайтовым ограничением. А во втором, когда параметр Foo, - с жёстким.
...Как принято поступать?
Наверное принято поступать так, как того требует решаемая задача...
Насколько понимаю, компилятор видит, что в качестве параметра ему передали class Foo & { ... }, но при вызове ::method() всё равно обращается к методу родительского класса, как к единственному разрешённому методу. Что неудивительно, с одной стороны. С другой, как бы легально обходим запрет, созданный с помощью delete. Получается, что спецификатор delete работает только при явном указании типа. Т.е. вот так уже не получится:
Интересно, что с виртуальным методом будет ошибка на этапе компиляции. А с обычным - просто вызов метода базового класса.
Возможно, виртуальные методы позволят более полноценно использовать delete в случаях, когда возможна передача по ссылке на базовый класс.
При закрытом наследовании тоже геморой - придется для других публичных методов что-то такое городить:
В общем, не до конца понимаю логику использования delete в этом контексте.
Умные дядьки предлагают для "чистого кода" наследоваться, вместо того, чтобы править существующий оттестированный код. Ага, легко сказать.
Хотя, вероятно, я просто изначально наплужил с архитектурой.Все это нормальное поведение в этом контексте наследования. Какие умники? Принцип OCP очень хорош, но НЕ связан с наследованием.
Какую реальную проблему вы пытаетесь решить?
Вероятно, вам следует использовать композицию вместо наследования.
Какие умники?
Я когда-то слышал утверждение, подобное тому, что я написал (что лучше унаследоваться, чем править существующий код). Но я не помню, где я это "слышал". Возможно, я что-то неправильно понял или моя память исказила информацию. Вероятно, наследование хорошо там, где его возможность изначально предусмотрена архитектурой.
Какую реальную проблему вы пытаетесь решить?
Мои рассуждения были порождены реальным кодом, но для того кода это не является проблемой и я его уже закончил. Я просто пытаясь обрести лучшее понимание сценариев использования тех или других возможностей языка.
Я когда-то слышал утверждение, подобное тому, что я написал (что лучше унаследоваться, чем править существующий код). Но я не помню, где я это "слышал". Возможно, я что-то неправильно понял или моя память исказила информацию. Вероятно, наследование хорошо там, где его возможность изначально предусмотрена архитектурой.
Мои рассуждения были порождены реальным кодом, но для того кода это не является проблемой и я его уже закончил. Я просто пытаясь обрести лучшее понимание сценариев использования тех или других возможностей языка.
"=delete" НЕ предназначено и не должно использоваться для изменения открытого интерфейса в контексте наследования. Это плохая практика, открытый интерфейс в иерархии классов следует уважать и следовать принципу Лисков.
По этой же причине его нельзя использовать с виртуальными функциями, так как это изменит «контракт» виртуального интерфейса.
(Надеюсь, перевод этих концепций ООП на русский язык понятен).
"=delete" НЕ предназначено и не должно использоваться для изменения открытого интерфейса в контексте наследования. Это плохая практика, открытый интерфейс в иерархии классов следует уважать и следовать принципу Лисков.
По этой же причине его нельзя использовать с виртуальными функциями, так как это изменит «контракт» виртуального интерфейса.
(Надеюсь, перевод этих концепций ООП на русский язык понятен).
Теперь все встало на свои места. Вы ответили на мои вопросы, спасибо большое!
Просьба объяснить логику такого поведения компилятора.
Только что случайно нашел в закладках браузера:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Ошибки, баги, вопросы
Ilyas, 2024.03.11 15:50
Потому, что C++ генерирует конструктор копирования по умолчанию, а MQL5 нет (пока/до сих пор).
Т.к. в вашем коде отсуствует конструктор копирования, то для возвращаемого объекта из "оператора копирования", вызывается: "конструктор по умолчанию" + "оператор копирования".
Получается рекурсия:
"оператор копирования" = "конструктор по умолчанию" + "оператор копирования".
На сколько я понимаю (могу ошибаться): MQL не генерирует неявный конструктор копирования, а неявный operator= не знает, что делать с константным полем.