Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Нет, не совсем понимаю. Мне хотелось-бы понимать не только эту функцию, а вообще как это работает… Из учебника и статей, а тем более из документации этого понять не могу.
В классе CTrade есть такие виртуальные функции
И мне кажется они никак не используются, если работать через этот класс.
В других местах есть другие. Вот и хочется понять как это работает.
Ну... скажем...
Смотри, тебе надо отслеживать некоторые ордера, которые ты отсылаешь на сервер (скажем, для статистики).
У тебя уже есть большой эксперт, с всяким анализом, условиями, кучей кода. Разбираться в нём, где можно взять статистику - сложно.
Но в этом эксперте, есть объект класса CTrade, у которого ты вызываешь метод SendOrder(). Метод виртуальный - а значит, тебе совершенно не надо смотреть весь код эксперта. Ты просто описываешь объект:
class CStatTrade: public CTrade
{
protected:
// Здесь переменные для сбора статистики.
public:
...
virtual bool OrderSend(const MqlTradeRequest &request,MqlTradeResult &result)
{
// Здесь ты собираешь стистику, и запоминаешь в protected-переменных класса CStatTrade
// А потом - вызываешь метод базового класса
return( CTrade::OrderSend(request,&result))
};
...
} // конец класса СStatTrade
И далее, в коде эксперта создаёшь вместо объекта CTrade - объект CMyTrade.
Все его методы пронаследованы, и он будет нормально работать.
А метод SendOrder - будет дополнительно ещё и собирать твою статистику. И потом, где надо - ты из созданного объекта CMyTrade - сможешь вытащить собранную статистику.
ВАЖНО!!!
В чем главная особенность виртуальной функции. При вызове SendOrder - у тебя есть две функции - базовая, и пронаследованная (и наследников может быть куча, с большой иерархией). И какая именно будет вызвана, определяется не в момент компиляции, а в момент создания объекта CTrade или CStatTrade.
Именно в этом суть виртуальных функций - если функции невиртуальны, то какая именно будет вызвана - решается в момент компиляции. А если виртуальны - то это определяется в момент создания объекта, у которого эта виртуальная функция будет вызвана. Это называется "позднее связывание"
Самое интересное как раз-таки осталось за кадром.
Что внутри? switch? dynamic_cast?
И это тоже. Макрос CONVERT_CONST_OBJECT_WITH_CHECK как раз проверяет тип объекта, с учётом того, что это не просто CObject, а CMyObject, там проверяется внутренний ID типа:
CMyObject* _PerformObjectConvertWithCheck(CMyObject* pmoObject,EMyObjectTypes motType) { ASSERT_MYPOINTER(pmoObject); // проверим указатель ASSERT(pmoObject.CheckType(motType) == true); // проверим внутренний ID типа объекта return(pmoObject); }; const CMyObject* _PerformConstObjectConvertWithCheck(const CMyObject* pmoObject,EMyObjectTypes motType) { ASSERT_MYPOINTER(pmoObject); // проверим указатель ASSERT(pmoObject.CheckType(motType) == true); // проверим внутренний ID типа объекта return(pmoObject); }; #define CONVERT_OBJECT_WITH_CHECK(objFrom,typeTo,checkType) ((typeTo*)_PerformObjectConvertWithCheck(objFrom,checkType)) #define CONVERT_CONST_OBJECT_WITH_CHECK(objFrom,typeTo,checkType) ((typeTo*)_PerformConstObjectConvertWithCheck(objFrom,checkType))Макросы ASSERT - в релизной версии пустые. Дебаг-версию - прикрпеляю.В чем главная особенность виртуальной функции. При вызове SendOrder - у тебя есть две функции - базовая, и пронаследованная. И какая именно будет вызвана, определяется не в момент компиляции, а в момент создания объекта CTrade или CStatTrade.
Именно в этом суть виртуальных функций - если функции невиртуальны, то какая именно будет вызвана - реашется в момент компиляции. А если виртуальны - то это определяется в момент создания объекта, у которого эта виртуальная функция будет вызвана.
Чуть дополню.
Можно, например, иметь массив/список указателей на базовый класс, а реально размещать там указатели на объекты различных производных, при переборе вызывать для них одну и ту же ф-цию (по названию), а реально будет вызываться вызываться ф-ция производного класса, возможно, у каждого своя, в зависимости от реального типа указателя.
Вот-вот!
Алексей, как раз про это я и написал в прошлом сообщении!
Если бы метод Compare() был бы невиртуальным, то какую из функций вызывать, определялось бы в момент компиляции. А там у нас указатель на класс CObject - функция именно этого объекта и была бы создана.
А вот если эта функция виртуальна, то какая именно функция будет вызвана - в момент компиляции ещё неизвестно. Это будет известно только тогда, когда ты будешь создавать объекты, пронаследованные от CObject. И именно функции этих создаваемых объектов будут вызываться.
Ну... скажем...
Смотри, тебе надо отслеживать некоторые ордера, которые ты отсылаешь на сервер (скажем, для статистики).
У тебя уже есть большой эксперт, с всяким анализом, условиями, кучей кода. Разбираться в нём, где можно взять статистику - сложно.
Но в этом эксперте, есть объект класса CTrade, у которого ты вызываешь метод SendOrder(). Метод виртуальный - а значит, тебе совершенно не надо смотреть весь код эксперта. Ты просто описываешь объект:
class CStatTrade: public CTrade
{
protected:
// Здесь переменные для сбора статистики.
public:
...
virtual bool OrderSend(const MqlTradeRequest &request,MqlTradeResult &result)
{
// Здесь ты собираешь стистику, и запоминаешь в protected-переменных класса CStatTrade
// А потом - вызываешь метод базового класса
return( CTrade::OrderSend(request,&result))
};
...
} // конец класса СStatTrade
И далее, в коде эксперта создаёшь вместо объекта CTrade - объект CMyTrade.
Все его методы пронаследованы, и он будет нормально работать.
А метод SendOrder - будет дополнительно ещё и собирать твою статистику. И потом, где надо - ты из созданного объекта CMyTrade - сможешь вытащить собранную статистику.
ВАЖНО!!!
В чем главная особенность виртуальной функции. При вызове SendOrder - у тебя есть две функции - базовая, и пронаследованная (и наследников может быть куча, с большой иерархией). И какая именно будет вызвана, определяется не в момент компиляции, а в момент создания объекта CTrade или CStatTrade.
Именно в этом суть виртуальных функций - если функции невиртуальны, то какая именно будет вызвана - реашется в момент компиляции. А если виртуальны - то это определяется в момент создания объекта, у которого эта виртуальная функция будет вызвана. Это называется "позднее связывание"
Откуда эти функции?
Видимо это не для моих мозгов. Но всё-же я постараюсь понять это.
Но всё-же я постараюсь понять это.
Виртуальные методы полезны только при использовании указателей. Если указатели не используются, virtual не пригодится.
Полно примеров для начинающих, где есть, например, множество Животное с виртуальной функцией звука от него. И есть его производные "подмножества": собаки, кошки и т.д. И у каждого из них своя реализация общей виртуальной функции звука: лай, мяуканье и т.д.
И если используются указатели, то можно собаку обобщить, сказав всем, что это Животное (указатель). Но при этом оно будет лаять.
В итоге можно, например, наплодить (создать объекты) собак, кошек и баранов. Затем загнать их в один одинаковый загон Животных (массив указателей на Животных). И, вроде, в массиве все Животные, но звук будет каждый издавать свой: лаять, мяукать, блеять.
Вот-вот!
Алексей, как раз про это я и написал в прошлом сообщении!
Если бы метод Compare() был бы невиртуальным, то какую из функций вызывать, определялось бы в момент компиляции. А там у нас указатель на класс CObject - функция именно этого объекта и была бы создана.
А вот если эта функция виртуальна, то какая именно функция будет вызвана - в момент компиляции ещё неизвестно. Это будет известно только тогда, когда ты будешь создавать объекты, пронаследованные от CObject. И именно функции этих создаваемых объектов будут вызываться.
То-есть функция в потомке просто заменяет функцию родителя?
Если так, то зачем всё это городить если простая функция будет работать так-же… В чём прикол? В чём полезность виртуальности?
Ну в том примере, что привёл я, это не я писал, там более-менее понятно. Внутри классов СArray и СArrayObj неоднократно вызывается метод Compare и в этом случае понятно будет замена. А вот объяснения с классом CTrade совсем не догоняю.
Виртуальные методы полезны только при использовании указателей. Если указатели не используются, virtual не пригодится.
Полно примеров для начинающих, где есть, например, множество Животное с виртуальной функцией звука от него. И есть его производные "подмножества": собаки, кошки и т.д. И у каждого из них своя реализация общей виртуальной функции звука: лай, мяуканье и т.д.
И если используются указатели, то можно собаку обобщить, сказав всем, что это Животное (указатель). Но при этом оно будет лаять.
В итоге можно, например, наплодить (создать объекты) собак, кошек и баранов. Затем загнать их в один одинаковый загон Животных (массив указателей на Животных). И, вроде, в массиве все Животные, но звук будет каждый издавать свой: лаять, мяукать, блеять.
Вот это понятней
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Интересное и Юмор
Alexey Viktorov, 2024.11.01 07:44
Доходчиво про объекты и указатели:
«Вообще, создание объектов через new - это как слепил шарик из какахи (чтобы соседу 1 на коврик положить потом) и кинул в мешок чтоб не воняло. Потом слепил второй шарик (для соседа 2) и тоже его в мешок... потом третий, четвёртый, десятый ... ну.. сколько соседей обрадовать хочешь - столько шариков в мешок.
И когда наступает час Ч ты понимаешь, что какахи не пронумерованы, и ты не знаешь какая принадлежит какому соседу... Засада, да?
Так вот - указатели - это верёвочки с бирочками с номерами соседа 1, 2, 3, 100 ... они привязаны к шарикам, которые в мешке (памяти), а второй конец с бирочками - у тебя в руках (в списке). Теперь по номеру соседа ты тянешь за нужную верёвочку (указатель) и достаёшь из мешка (памяти) нужную какаху (объект), получая к нему доступ и делая с ним нужные делишки.»
Вот это понятней
Написал про виртуальные функции, а не про указатели.
Написал про виртуальные функции, а не про указатели.
Вот это полезно и понятно. За это спасибо.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Учёба. Классы. Нужна помощь.
fxsaber, 2024.12.16 10:30
Виртуальные методы полезны только при использовании указателей. Если указатели не используются, virtual не пригодится.