Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
George Merts
Стандартный CObject - это "объект списка или сортированного массива". CMyObject - это CObject, имеющий определенный тип, и содержащий некоторое значение, данное при его создании. Этот объект мне понадобился всвязи с повсеместным приведением объектов к базовому абстрактному классу - чтобы понимать по указателю, на какой именно объект "на самом деле" указывает. Тип CMyObject - устанавливается как раз той самой функцией SetMyObjectType(). Эта функция в обязательном порядке вызывается в конструкторах любых наследников от CMyObject, чтобы назначить идентификатор класса, к которому принадлежит создаваемый объект.
У Вас конструктор открытый и непараметризованный:
Это значит, что наследник может установить свой тип, а может и не установить. Т.е. если внутри наследника забудете вызвать метод SetMyObjectType - пиши пропало.
Что можно сделать?
1. Закрыть конструктор от создания из вне:
Тогда, создать экземпляр сможет только потомок CTradeHistoryI, а значит необходимость в типе MOT_TRADE_HISTORY_I - отпадет. Замечу, что тип MOT_TRADE_HISTORY_I никогда не существует в действительности, т.к. CTradeHistoryI - интерфейс, и не может быть экземпляра с этим типом. Т.е. закрыв конструктор мы решаем противоречие - описание несуществующего типа.
2. Зададим требование явной типизации в момент создания экземпляра:
Все, теперь ни один потомок не сможет создать себя без явного задания типа.
Зачем изобретать велосипед в виде CMyObject, когда есть стандартный и всем понятный CObject?
Уж не знаю, что хорошего вы нашли в MQL-овском CObject. Два ненужных указателя, запихиваемых в каждый объект = 16 потерянных байт + лишний оверхед при выделении памяти и инциализации этих указателей. ООП сам по себе замедляет производительность, а если ещё и такие бестолковые решения...
Выучите ООП для начала, потом обсудим. Инициализация m_prev, m_next в общем случае не происходит если что.
Выучите ООП для начала, потом обсудим. Инициализация m_prev, m_next в общем случае не происходит если что.
Только после вас.
И так для сведений, инициализация указателей в MQL производится всегда.
У Вас конструктор открытый и непараметризованный:
Это значит, что наследник может установить свой тип, а может и не установить. Т.е. если внутри наследника забудете вызвать метод SetMyObjectType - пиши пропало.
Что можно сделать?
...
Да, действительно, я в некоторых случаях забываю указать SetMyObjectType() - и объекты создаются с типом CMyObject по умолчанию.
И метод решения - хороший.
Предложения принимаются.
Хотя, протектед-конструктор мне не нравится.
Да, действительно, я в некоторых случаях забываю указать SetMyObjectType() - и объекты создаются с типом CMyObject по умолчанию.
И метод решения - хороший.
Предложения принимаются.
Хотя, протектед-конструктор мне не нравится.
Протектед-конструктор усложняет жизнь только тем классам, которые непосредственно наследуются от родителя с таким конструктором. Но вот на пользовательском уровне, создавать производные объекты можно не задумываясь и свободно.
Поэтому неудобство наблюдаться не должно.
Ну и других вариантов в MQL нет, т.к. нет системы контроля типов, вернее она есть, но в недоразвитом виде, вот и приходится защищать тип через скрытие конструктора.
Уж не знаю, что хорошего вы нашли в MQL-овском CObject. Два ненужных указателя, запихиваемых в каждый объект = 16 потерянных байт + лишний оверхед при выделении памяти и инциализации этих указателей. ООП сам по себе замедляет производительность, а если ещё и такие бестолковые решения...
Да почему "бестолковые" ? Оверхед - по-моему, очень небольшой, и он явно стоит удобства, которые дает CObject при организации списков и сортированных массивов.
Если нам надо гоняться за микросекундами и байтами - то, конечно, имеет смысл прикинуть - а не слишком ли большие ресурсы приходятся на эти самые "потерянные байты". Но, как показывает моя практика - удобство написания и поддержки кода - гораааздо важнее.
Кстати, совсем недавно возился с оптимизацией кода - мои советники как-то слишком медленно работали в тестере. Наиболее медленная функция была в рефреше данных. Ну, соответственно, я всеми способами старался уменьшить обращение к этому рефрешу. Но, недавно появилась возможность профилирования кода в тестере. И к моему огромному удивлению, я увидел, что большую часть времени советник тратит на ненужную (почти) мне функцию запроса состояния терминала (она проводилась при каждом рефреше, и просто делалась "заодно" с остальными). И больше всего - тратилось на функцию запроса свободной памяти. Небольшое изменение кода, чтобы состояние терминала запрашивалось только один раз при старте, а потом при рефрешах - только при явном указании - ускорило тестирование более чем втрое !
Так что "ненужный оверхед" может теряться совсем не там, где мы его ищем.
Так что "ненужный оверхед" может теряться совсем не там, где мы его ищем.
Да почему "бестолковые" ? Оверхед - по-моему, очень небольшой, и он явно стоит удобства, которые дает CObject при организации списков и сортированных массивов.
Эти "удобства" реализованы через одно место. Что это за список такой, который что-то меняет в твоих объектах? По сути получается что константные объекты нельзя поместить в список. Или вот представь ситуацию, что твой объект, находящийся в таком списке, ты отправляешь в некую функцию, которая тоже помещает его в свой список, и потом получаешь обратно свой объект с изменённым prev и next, и пошло поехало...
В цивилизованном мире списки реализуются через вспомогательные объекты Node, хранящие требуемые указатели. А трогать сами объекты пользователя - это нонсенс. Так что дело не только в оверхеде, а в принципиальной неправильности всего этого. Разработчики что-то слепили на скорую руку, а вы и рады, будто так и должно быть.
Эти "удобства" реализованы через одно место. Что это за список такой, который что-то меняет в твоих объектах? По сути получается что константные объекты нельзя поместить в список. Или вот представь ситуацию, что твой объект, находящийся в таком списке, ты отправляешь в некую функцию, которая тоже помещает его в свой список, и потом получаешь обратно свой объект с изменённым prev и next, и пошло поехало...
В цивилизованном мире списки реализуются через вспомогательные объекты Node, хранящие требуемые указатели. А трогать сами объекты пользователя - это нонсенс. Так что дело не только в оверхеде, а в принципиальной неправильности всего этого. Разработчики что-то слепили на скорую руку, а вы и рады, будто так и должно быть.
Ну, да, константные объекты в список не запишешь.
Но, при этом я постоянно пользуюсь функциональностью CObject, а никто из критиков ничего даже похожее на объекты массивы и списки Стандартной Библиотеки - не предложил.
"Как надо делать" - это каждый горазд орать. А вот предложить что-то - и ВНЕЗАПНО оказывается нечего.
Даже те участники, кто реально предлагают различные программные решения - не предлагают замены CObject'y - чаще вобще его не используют, реже используют его функциональность, не обращая внимания на "реализацию через одно место". А значит - реализация вполне себе годная.
Была бы плохая - давно бы уже предложили замену.