Можно примерно так:
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ class CInfo { public: string symbol; ENUM_TIMEFRAMES timeframe; MqlRates rates[]; public: //--- Конструктор и деструктор CInfo(void){}; ~CInfo(void){ Print(symbol," ", EnumToString(timeframe)); }; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnStart() { CInfo *arInfo[1]; arInfo[0] = returnInfo(); if(CheckPointer(arInfo[0])) { delete arInfo[0]; } } //+------------------------------------------------------------------+ CInfo *returnInfo() { CInfo *i = new CInfo(); i.symbol=_Symbol; return i; } //+------------------------------------------------------------------+
Т.е. работать по указателю. Но обязательно не забывать удалять объекты (delete), созданные оператором new!
Документация: https://www.mql5.com/ru/docs/basis/types/object_pointers, https://www.mql5.com/ru/docs/basis/operators/newoperator, https://www.mql5.com/ru/docs/basis/operators/deleteoperator
Статья на тему: https://www.mql5.com/ru/articles/36
- www.mql5.com
Добрый день! Помогите разобраться как правильно решить такую задачу: Создать объект пользовательского класса, вернуть его функцией и поместить в массив.
Ошибка в том, что вы создаете объект локально в функции ReturnInfo(), обычно считается что такие объекты уничтожаются при выходе из функции. Но вы перед уничтожением его возвращаете. Если бы это была простая переменная - никаких бы проблем не возникло, объект скопировался в вашу внешнюю переменную, а внутренний, тот, что был в функци - уничтожился бы. У вас же объект содержит сложные структуры, которые при копировании также надо скопировать. О том вам и говорит первая ошибка - структура имеет объекты и не может быть просто скопирована.
Решение проблемы имеет два варианта - на первый вам прямо указала вторая ошибка, вам следует в описании объекта CInfo создать конструктор копирования с прототипом 'CInfo::CInfo(const CInfo &)' - и тогда ваш код заработает.
Второй вариант правильно указан Sergey Eremin - объект создается с помощью оператора new, и потом везде с ним работают через указатель. В этом случае, тоже правильно сказано - надо не забывать удалять объекты после того, как они вам перестанут быть нужны.
Лично мне больше нравится второй вариант, но начинающим бы я рекомендовал первый, как более простой.
Можно примерно так:
Т.е. работать по указателю. Но обязательно не забывать удалять объекты (delete), созданные оператором new!
Документация: https://www.mql5.com/ru/docs/basis/types/object_pointers, https://www.mql5.com/ru/docs/basis/operators/newoperator, https://www.mql5.com/ru/docs/basis/operators/deleteoperator
Статья на тему: https://www.mql5.com/ru/articles/36
Спасибо что помогаете! Извините за наглость, если не сложно покажите еще как вернуть такой массив указателей и встретить его в переменную для дальнейшего манипулирования.
в данных попытках ошибки:
void OnStart() { CInfo *arInfo[]; arInfo=ReturnArrayInfo();//Получить массив объектов CInfo //теперь можно все уничтожить for(int j=0;j<ArraySize(arInfo);j++) { if(CheckPointer(arInfo[j])) { Print("Уничтожение "+j); delete arInfo[j]; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CInfo[] *ReturnArrayInfo() { CInfo *arInfo[]; for(int j=0;j<10;j++) { CInfo *i=returnInfo(); if(CheckPointer(i)==POINTER_DYNAMIC) { ArrayResize(arInfo,ArraySize(arInfo)+1); arInfo[ArraySize(arInfo)-1]=i; } } return arInfo; } //+------------------------------------------------------------------+ CInfo *returnInfo() { CInfo *i= new CInfo(); i.symbol=_Symbol; return i; }
Спасибо что помогаете! Извините за наглость, если не сложно покажите еще как вернуть такой массив указателей и встретить его в переменную для дальнейшего манипулирования.
в данных попытках ошибки:
Ммм, я бы сделал примерно так (но проверял в "полглаза", так что посмотрите сами, всё ли корректно работает):
class CInfo { public: string symbol; ENUM_TIMEFRAMES timeframe; MqlRates rates[]; public: //--- Конструктор и деструктор CInfo(void){}; ~CInfo(void){ Print(symbol," ", EnumToString(timeframe)); }; }; void OnStart() { CInfo *arInfo[]; ReturnArrayInfo(arInfo);//Получить массив объектов CInfo //теперь можно все уничтожить for(int j=0;j<ArraySize(arInfo);j++) { if(CheckPointer(arInfo[j])) { Print("Уничтожение "+j); delete arInfo[j]; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ReturnArrayInfo(CInfo *&arInfo[]) { for(int j=0;j<10;j++) { CInfo *i=returnInfo(); if(CheckPointer(i)==POINTER_DYNAMIC) { ArrayResize(arInfo,ArraySize(arInfo)+1); arInfo[ArraySize(arInfo)-1]=i; } } } //+------------------------------------------------------------------+ CInfo *returnInfo() { CInfo *i= new CInfo(); i.symbol=_Symbol; return i; }
Т.е. функция не возвращает массив, а ей передаётся массив указателей на объекты по ссылке (надеюсь верно выразился; если что, думаю меня поправят). А с этим массивом уже работаем в функции.
Документация (о передаче по ссылке): https://www.mql5.com/ru/docs/basis/types/this
P.S. не за что, лично мне всегда приятно помогать тем, кто пытается искать решения самостоятельно :)
- www.mql5.com
в данных попытках ошибки:
Насколько я понимаю, вы опять делаете ту же ошибку - сперва объявляете массив указателей на CInfo, потом заполняете его, а потом - возвращаете с одновременным уничтожением. При этом функция ReturnArrayInfo()
у вас, насколько я вижу объявлена, как возвращающая указатель на массив, а в ее коде возвращается сам массив.
Вам следует почитать про создание объектов. В чем разница создания объекта, когда вы его просто объявляете в коде (создание объекта на стеке) и когда вы используете оператор new (создаете объект в "куче"). Обратить внимание на время жизни объекта, и порядку обращения к ним.
Спасибо что помогаете! Извините за наглость, если не сложно покажите еще как вернуть такой массив указателей и встретить его в переменную для дальнейшего манипулирования.
в данных попытках ошибки:
Если работаете с объектами, то ВСЕГДА используйте стандартную библиотеку и контейнер CArraObj. Он для того и написан, что бы взять на себя работу по выделению памяти для объектов и их удаления "за кулисами". С ним в разы сокращается пользовательский код. Вот как с ним будет выглядеть Ваш алгоритм:
#include <Object.mqh> #include <Arrays\ArrayObj.mqh> class CInfo : public CObject { public: string symbol; ENUM_TIMEFRAMES timeframe; MqlRates rates[]; public: //--- Конструктор и деструктор CInfo(void){}; CInfo(string symbol){this.symbol = symbol;} ~CInfo(void){ Print(symbol," ", EnumToString(timeframe)); }; }; void OnStart() { CArrayObj ListInfo; // Добавляем десять элементов типа CInfo for(int i = 0; i < 10; i++) ListInfo.Add(new CInfo(Symbol()); //Можно выйти и забить на ListInfo, все элементы в нем будут уничтожены автоматически! }Т.е. получается, что никаких массивов указателей объявлять не нужно. Не нужно из переразмечать, инициализировать и удалять из них объекты. Все это уже давно сделано в классе CArrayObj. Нам осталось лишь многократно пользоваться его функционалом.
Если работаете с объектами, то ВСЕГДА используйте стандартную библиотеку и контейнер CArraObj. Он для того и написан, что бы взять на себя работу по выделению памяти для объектов и их удаления "за кулисами". С ним в разы сокращается пользовательский код. Вот как с ним будет выглядеть Ваш алгоритм:
Т.е. получается, что никаких массивов указателей объявлять не нужно. Не нужно из переразмечать, инициализировать и удалять из них объекты. Все это уже давно сделано в классе CArrayObj. Нам осталось лишь многократно пользоваться его функционалом.Если делом всей жизни является написание одной единственной программы.
Если класс включает сотню методов и свойств, как кодить с таким подходом? Постоянно лазить в файл с классом и смотреть как там точно метод называется?
Если делом всей жизни является написание одной единственной программы.
Как раз все наоборот. Это если вы пишете одну программу - можете не пользоваться всякими ООП-наворотами, весь советник написать в одном файле, и не писать ни одного комментария.
А вот если вы пишете много программ - то использование Стандартной Библиотеки - очень повышает эффективность написания кода и дальнейшую его поддержку.
Если класс включает сотню методов и свойств, как кодить с таким подходом? Постоянно лазить в файл с классом и смотреть как там точно метод называется?
Если класс имеет сотню методов и свойств - этот класс плохо продуман. Класс должен иметь только те методы и свойства, которые относятся непосредственно к нему самому, и если их больше десятка - это уже говорит о недостаточно хорошо продуманной структуре.
Ну а насчет "как упомнить названия методов" - дык именно так и делать, смотреть в .mqh-файл с заголовком класса. Все частые методы - быстро запоминаются. А за редкими - можно и заглянуть. (Считаю, что ни одно свойство не должно быть доступно извне, доступ к свойствам только через функции типа GetValue()).
Как раз все наоборот. Это если вы пишете одну программу - можете не пользоваться всякими ООП-наворотами, весь советник написать в одном файле, и не писать ни одного комментария.
А вот если вы пишете много программ - то использование Стандартной Библиотеки - очень повышает эффективность написания кода и дальнейшую его поддержку.
Если класс имеет сотню методов и свойств - этот класс плохо продуман. Класс должен иметь только те методы и свойства, которые относятся непосредственно к нему самому, и если их больше десятка - это уже говорит о недостаточно хорошо продуманной структуре.
Пункт X! Ну а насчет "как упомнить названия методов" - дык именно так и делать, смотреть в .mqh-файл с заголовком класса. Все частые методы - быстро запоминаются. А за редкими - можно и заглянуть. (Считаю, что ни одно свойство не должно быть доступно извне, доступ к свойствам только через функции типа GetValue()).
А расскажи мне про таблицу умножения, какая она правильная.
X. Вот и флаг вам в руки и барабан на шею. Вот это прогресс, вот это ООП! Нафиг бы тогда этот ООП вообще. Еще рассуждаете тут о том, какие классы правильные, какие нет.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Добрый день! Помогите разобраться как правильно решить такую задачу: Создать объект пользовательского класса, вернуть его функцией и поместить в массив.
ошибки:
'=' - structure have objects and cannot be copied classTest.mq5 25 13
object of 'CInfo' cannot be returned, copy constructor 'CInfo::CInfo(const CInfo &)' not found classTest.mq5 33 11