- MetaEditor. Проблемы и решения.
- Раньше можно было в тех поддержку обратиться с вопросом, когда на форуме не помогли
- Ошибки, баги, вопросы
Можно в стиле Java/C# весь класс оформить.
Разделение в С-стиле нужно ТОЛЬКО при публикации закрытой библиотеки.
Возможно ли каким то образом, нормально разбивать код на mqh и mq5 по аналогии с hpp и cpp? Крайне неудобно иметь обьявление класса и его код в одном mqh файле. Понятно что в MQL5 нет понятия обьектных файлов для каждого mq5 и собираются они все в кучу, но хотя бы не для скорости сборки, а для удобства это можно как то сделать?
Конечно можно, я так пишу сам, удобно
У меня все оформлено через классы, которые лежат в *.mqh. Общие функции завернуты в классы, как статические методы. Классы разбиты по темам.
Например, кусок файла d:\Project\MQL5\Include\Cayman\UFile.mqh
#property copyright "Copyright 2020, Malik Arykov" #property link "www.cayman-pro.ga" #include <Arrays/ArrayString.mqh> // флаги функции FileOpen #define FILE_READ_UTF8 (int)(FILE_SHARE_READ|FILE_ANSI) #define FILE_WRITE_UTF8 (int)(FILE_READ|FILE_WRITE|FILE_ANSI) #define FILE_READ_UNICODE (int)(FILE_SHARE_READ|FILE_UNICODE) #define FILE_WRITE_UNICODE (int)(FILE_READ|FILE_WRITE|FILE_UNICODE) // ----------------------------------------------------------------------------- // Файловые функции // ----------------------------------------------------------------------------- class UFile { public: static bool IsDirectory(string path); static string Parent(string path); static string FileName(string path); static string FileNameWithoutExt(string path); static int FindFiles(string path, CArrayString *paths); static string LoadText(string path, int flags, CArrayString *lines); static bool SaveText(string text, string path, int flags, bool reset); static bool SaveText(CArrayString *lines, string path, int flags, bool reset); }; // ----------------------------------------------------------------------------- // Проверить является ли путь существующим каталогом // ----------------------------------------------------------------------------- static bool UFile::IsDirectory(string path) { ResetLastError(); bool isFile = FileIsExist(path); return (_LastError == 5018); } ...
вопрос к профи, все разбивают классы на отдельные файлы?
привык работать с с обычными функциями, в одном файле по направлениям
Дублирование объявления функции в С-стиле оправдано только для закрытия кода при публикации кода. Но редактировать аргументы нужно в ДВУХ местах! Зачем?
MQL проектируют Си-шники, поэтому они классы разбивают по привычке. Забавно, что при разбивки класса не разделяют его на файлы - бессмыслица. Но даже в С++ можно ВЕСЬ код класса запихать в .hpp (Java/C# стиль) и потерять на времени прекомпиляции - а этого в MQL нет изначально.
https://github.com/Roffild/RoffildLibrary/tree/master/Include/Roffild - Java/C# стиль
- Roffild
- github.com
Java/C# стиль:
/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * https://github.com/Roffild/RoffildLibrary */ #include "ArrayListClass.mqh" class CStatisticObject { public: ulong hash; int count; string describe; CStatisticObject(const ulong _hash, const string _describe = "none", const int _count = 0) { hash = _hash; describe = _describe; count = _count; } }; /** * Counting data and printing out the accumulated information. */ class CStatistic { public: CArrayListClass<CStatisticObject> object; string name; CStatistic() { name = "NoName"; } ~CStatistic() { print(); } int index(const ulong hash) { const int count = object.size(); for (int x = 0; x < count; x++) { if (object[x].hash == hash) { return x; } } return -1; } int plus(const ulong hash, const string describe = "none", const int number = 1) { const int ind = index(hash); if (ind > -1) { return object[ind].count += number; } if (object.add(new CStatisticObject(hash, describe))) { return object[object.size() - 1].count += number; } return 0; } int plus(CStatisticObject *value, const int number = 1) { const int ind = index(value.hash); if (ind > -1) { delete value; return object[ind].count += number; } if (object.add(value)) { return object[object.size() - 1].count += number; } delete value; return 0; } void print(const int file = INVALID_HANDLE) { if (file == INVALID_HANDLE) { if (MQLInfoInteger(MQL_OPTIMIZATION) == false) { Print("=== ", name, " -- Statistic ==="); const int count = object.size(); for (int x = 0; x < count; x++) { Print(object[x].describe, " = ", object[x].count); } } } } };
Дублирование объявления функции в С-стиле оправдано только для закрытия кода при публикации кода. Но редактировать аргументы нужно в ДВУХ местах! Зачем?
MQL проектируют Си-шники, поэтому они классы разбивают по привычке. Забавно, что при разбивки класса не разделяют его на файлы - бессмыслица. Но даже в С++ можно ВЕСЬ код класса запихать в .hpp (Java/C# стиль) и потерять на времени прекомпиляции - а этого в MQL нет изначально.
https://github.com/Roffild/RoffildLibrary/tree/master/Include/Roffild - Java/C# стиль
Разделение интерфейса и реализации удобно в первую очередь тем, что проектирование интерфейса и реализации можно вести в двух разных файлах, быстро переключаясь между интерфейсом и реализацией. Так же, при просмотре комитов в гите сразу видно, поменялся интерфейс или его реализация. Так же, что бы отдать интерфейс программисту без кода - приходится его вручную вырезать. Кроме этого, не ясно, для чего тода в принципе, даны mq5 файлы. Типа "главный файл в котором main"?
Разделение класса в одном mqh - бессмысленное дублирование кода. И "интерфейсы" в текущей системе наследования - тоже бред полный. До идеи Java/C# не дотянули.
Разделение класса на mqh и mq5 - это вроде вообще не работает. Я пробовал разделить библиотеку сгенерированного кода на 1МБ для ускорения компиляции. Разделение библиотеки на закрытый код:
// lib.mq5 void getInputsForNetDump(double &inputs[]) export { #include "../../Files/headers/InputsForNet_dump.mqh" } // lib.mqh #import "lib.ex5" void getInputsForNetDump(double &inputs[]); #import
Эти же import/export не совместимы с классами! Или уже пофиксили?
#include "lib.mq5" void func() { double inputs[100]; getInputsForNetDump(inputs); }
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования