Ты путаешь понятия класс и экземпляр класса.
В твоем случае - ты создаешь два объекта CExpertTrade - один на стеке, другой по new, приравниваешь указатель одного к другому (теряешь один из объектов), а затем вызываешь функцию покупки у класса, а не у объекта. Это ошибка - функции можно вызывать только у объектов. Исключение - статические функции, но и они вызываются другим синтаксисом (через двойное двоеточие)
Правильно будет так:
// Объявляем указатель, создаем объект, и приравниваем полученный указатель объявленнному. CExpertTrade m_trade* = new CExpertTrade(); // Вызываем у созданного объекта (по указателю) функцию покупки. m_trade.BUY();
Ты путаешь понятия класс и экземпляр класса.
Не путаю. Просто думал об указателе и описался)) Я выше поправил то, что думаю.
В твоем случае - ты создаешь два объекта CExpertTrade - один на стеке, другой по new, приравниваешь указатель одного к другому (теряешь один из объектов), а затем вызываешь функцию покупки у класса, а не у объекта. Это ошибка - функции можно вызывать только у объектов. Исключение - статические функции, но и они вызываются другим синтаксисом (через двойное двоеточие)
Ну так если функции можно вызвать только у объектов, то почему в моём случае функция вызывается не из объекта? Ведь функция Buy() не является статичной. Вот она:
bool CTrade::Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") { CSymbolInfo sym; //--- check volume if(volume<=0.0) { m_result.retcode=TRADE_RETCODE_INVALID_VOLUME; return(false); } //--- check symbol sym.Name((symbol==NULL)?Symbol():symbol); //--- check price if(price==0.0) { sym.RefreshRates(); price=sym.Ask(); } //--- return(PositionOpen(sym.Name(),ORDER_TYPE_BUY,volume,price,sl,tp,comment)); }
Структуры, классы и интерфейсы
Даже говорить не о чем.
Ну вот смотрите. В первом после я показал как вызывается метод Buy. Причём экземпляр через new не создавался. А пройдя по ссылке я вижу, что:
// CFoo foo; // такой вариант использовать нельзя - конструктор по умолчанию не задан //--- допустимые варианты создания объекта CFoo CFoo foo1(TimeCurrent()); // явный вызов параметрического конструктора CFoo foo2(); // явный вызов параметрического конструктора с параметром по умолчанию CFoo foo3=D'2009.09.09'; // неявный вызов параметрического конструктора CFoo foo40(foo1); // явный вызов конструктора копирования CFoo foo41=foo1; // неявный вызов конструктора копирования CFoo foo5; // явный вызов конструктора по умолчанию (если конструктор по умолчанию отсутствует, // то вызывается параметрический конструктор с параметром по умолчанию) //--- допустимые варианты получения указателей CFoo CFoo *pfoo6=new CFoo(); // динамическое создание объекта и получение указателя на него CFoo *pfoo7=new CFoo(TimeCurrent());// ещё один вариант динамического создания объекта CFoo *pfoo8=GetPointer(foo1); // теперь pfoo8 указывает на объект foo1 CFoo *pfoo9=pfoo7; // pfoo9 и pfoo7 указывают на один и тот же объект // CFoo foo_array[3]; // такой вариант использовать нельзя - конструктор по умолчанию не задан
Такого варианта я не увидел в справке. Опять же возникл вопрос, как вызывалась функция (метод) из не объекта, в случает, если этот объект не статический. Если бы метод был статический, я бы не спрашивал. А в этом случает не всё однозначно..
Ну вот смотрите. В первом после я показал как вызывается метод Buy. Причём экземпляр через new не создавался. А пройдя по ссылке я вижу, что:
Такого варианта я не увидел в справке. Опять же возникл вопрос, как вызывалась функция (метод) из не объекта, в случает, если этот объект не статический. Если бы метод был статический, я бы не спрашивал. А в этом случает не всё однозначно..
Выбирайте
#include <Expert\ExpertTrade.mqh> CExpertTrade m_trade; void fun() { m_trade.Buy(...); }
#include <Expert\ExpertTrade.mqh> class CMyClass { private: CExpertTrade *m_trade; void fun() { m_trade.Buy(...); }; public: CMyClass() { m_trade = new CExpertTrade; }; ~CMyClass() { if(m_trade) delete m_trade; }; };
#include <Expert\ExpertTrade.mqh> class CMyClass : public CExpertTrade { private: void fun() { Buy(...); }; public: CMyClass(){}; ~CMyClass(){}; };
Я так понимаю, если не нужно использовать именно свойства самого объекта, а лишь пользоваться функциями, то можно пользоваться указателями и не создавать объекты через new. Я верно понимаю? Вчера почитал статьи здесь и понял, что имелось ввиду что-то в этом плане.
Кстати, вот по этому коду вопрос:
#include <Expert\ExpertTrade.mqh> class CMyClass { private: CExpertTrade *m_trade; void fun() { m_trade.Buy(...); }; public: CMyClass() { m_trade = new CExpertTrade; }; ~CMyClass() { if(m_trade) delete m_trade; }; };
Как вообще может такое писаться?
if(m_trade) delete m_trade;
Ведь m_trade это не булевая переменная, а указатель.. Как это условие вообще исполняется?
Я так понимаю, если не нужно использовать именно свойства самого объекта, а лишь пользоваться функциями, то можно пользоваться указателями и не создавать объекты через new. Я верно понимаю? Вчера почитал статьи здесь и понял, что имелось ввиду что-то в этом плане.
Кстати, вот по этому коду вопрос:
Как вообще может такое писаться?
Ведь m_trade это не булевая переменная, а указатель.. Как это условие вообще исполняется?
Так обратите внимание на это
m_trade = new CExpertTrade;
А писаться такое может по простой причине. Прежде чем удалять объект ни когда не помешает проверить, а есть ли он вообще и не был ли удален ранее.
Можно и так разыграть
#include <Expert\ExpertTrade.mqh> CExpertTrade *m_trade; void fun() { m_trade = new CExpertTrade; m_trade.Buy(...); delete m_trade; }
Я вам давал выше ссылку. Буковок много, но прочитать думаю все-же можно.
Так обратите внимание на это
А писаться такое может по простой причине. Прежде чем удалять объект ни когда не помешает проверить, а есть ли он вообще и не был ли удален ранее.
Можно и так разыграть
Я вам давал выше ссылку. Буковок много, но прочитать думаю все-же можно.
Так я по вашей ссылке прочёл всё. Остались некоторые моменты, которые не сразу уложились в голове, и я их паралельно проверяю в тестовом варианте.
По сути, то что нужно проверять указатель это понятно. Но более логично проверить будет в вашем случае вот так:
#include <Expert\ExpertTrade.mqh> CExpertTrade *m_trade; void fun() { m_trade = new CExpertTrade; if (CheckPointer(m_trade) == POINTER_INVALID) Print(__FUNCTION__," переменная 'obect' не инициализирована!"); delete m_trade; }
А вот такое:
if(m_trade) delete m_trade;
На первый взгляд не читабельно т.к. я привык пользоваться такими проверками сугубо для булевых переменных..
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Я прошерстил тему указателей, и, в принципе мне стало понятно как ими пользоваться и зачем они нужны в теории, но, т.к. я работал больше с языками, где есть гарбэдж коолекторы т.к. виртуальная машина сами высвобождает память при необходиомсти и в нужный момент, то есть некоторые вопросы. Вот, например, я открыл код эксперта ExpertMACD, который идёт в базовой поставке в платформой и решил поглядеть как там написан код, больше для того, что бы увидеть как работать с указателями. И я увидел эти моменты. Вот например:
CExpertTrade *m_trade; // trading object
Вызывается метод из класса
Я так понимаю вызывать методы из класса можно только по ссылке на адресс класса т.е. из указателя на класс? Меня смущает то, что в Java или С# это можно сделать проще... Вызвать из объекта т.е. экземпляра класса. Там было бы вот так:
Такой вариант получается в С++ и в МКЛ соответственно не прокатывает?