Создать массив своих объектов. Вернуть элемент класса функцией и поместить его в массив. - страница 2

 
Dmitry Fedoseev:

А расскажи мне про таблицу умножения, какая она правильная.

X. Вот и флаг вам в руки и барабан на шею. Вот это прогресс, вот это ООП! Нафиг бы тогда этот ООП вообще. Еще рассуждаете тут о том, какие классы правильные, какие нет. 

Ничего не понял. Поясните.

По делу у вас есть что возразить-то ? По-вашему, классы нужны для одной программы ? И по-вашему, в классе сто методов - это хорошо ?

 
George Merts:

Ничего не понял. Поясните.

По делу у вас есть что возразить-то ? По-вашему, классы нужны для одной программы ? И по-вашему, в классе сто методов - это хорошо ?

Вы ничего не поняли гораздо раньше.
 
Dmitry Fedoseev:
Вы ничего не поняли гораздо раньше.

Во-во. Продолжаются пустые обвинения. Я действительно не понял.

Ну а по делу что скажете ? ООП и Стадартная библиотека, по-вашему, не нужны ? А в классе должно быть сто методов ?

 
Dmitry Fedoseev:

Если делом всей жизни является написание одной единственной программы.

Если класс включает сотню методов и свойств, как кодить с таким подходом? Постоянно лазить в файл с классом и смотреть как там точно метод называется?

1. Тогда тем более используйте стандартную библиотеку, т.к. 95% функций которые Вам нужны, уже скорее всего написаны, многократно отлажены, оптимизированы и опробированы сотнями пользователей. Нет ничего легче, чем написать: ListInfo.Add(new CInfo()); на задумываясь о всяком там выделении/удалении памяти, переразметки массивов и прочей там ерунде. Не в 80-ых годах живем, все-таки. 

2. Перефразирую: если программа включает в себя сотни неструктурированных, разбросанных по разным mqh файлам функций, если не понятно, какие функции за какие классы задач отвечают, то как всем этим управлять и развивать проект? Т.е. Ваше утверждение относится в первую очередь именно к процедурному а не ООП программированию. В ООП-проектах с этим намного лучше, хотя бы потому что существенная (зачастую большая) часть методов реализована в секции private и не доступна для вызовов.

3. IntelliSense рулит. 

 
George Merts:

Как раз все наоборот. Это если вы пишете одну программу - можете не пользоваться всякими ООП-наворотами, весь советник написать в одном файле, и не писать ни одного комментария.

А вот если вы пишете много программ - то использование Стандартной Библиотеки - очень повышает эффективность написания кода и дальнейшую его поддержку.

Если класс имеет сотню методов и свойств - этот класс плохо продуман. Класс должен иметь только те методы и свойства, которые относятся непосредственно к нему самому, и если их больше десятка - это уже говорит о недостаточно хорошо продуманной структуре.

Ну а насчет "как упомнить названия методов" - дык именно так и делать, смотреть в .mqh-файл с заголовком класса. Все частые методы - быстро запоминаются. А за редкими - можно и заглянуть. (Считаю, что ни одно свойство не должно быть доступно извне, доступ к свойствам только через функции типа GetValue()).

Использование стандартной библиотеки повышает производительность в любом случае: пишите ли Вы одну программу или множество. Преимущества видны сразу. Простой пример был дан выше: алгоритм топикстартера с использованием ООП свелся к описанию собственно класса и простенького цикла for.

Помимо эффективности есть вторая производная - скорость разработки проекта. Так вот, с увеличением объема исходного кода, скорость разработки падает, т.к. приходится все больше внимания уделять отладке и взаимодействию между модулями программы. И здесь без ООП уже не обойтись, т.к. только с помощью этого подхода можно контролировать свой проект в целом. 

Если класс имеет сотню методов и свойств - этот класс плохо продуман. Класс должен иметь только те методы и свойства, которые относятся непосредственно к нему самому, и если их больше десятка - это уже говорит о недостаточно хорошо продуманной структуре.

Плюсую. Но уточню: не важно сколько приватных методов имеет класс, важно сколько публичных методов в нем есть. Чем меньше публичных методов, тем проще класс с точки зрения внешнего пользователя. Можно создать класс, выполняющий очень большой объем работы, однако с т.з. внешнего пользователя, он будет действовать элементарно просто: нажал на кнопку и получил результат.

Ну а насчет "как упомнить названия методов" - дык именно так и делать, смотреть в .mqh-файл с заголовком класса. Все частые методы - быстро запоминаются. А за редкими - можно и заглянуть. (Считаю, что ни одно свойство не должно быть доступно извне, доступ к свойствам только через функции типа GetValue()).

 GetValue не является панацеей, т.к. все равно потребуется создавать перечисления, содержащие множество значений. Но тем не менее, это все равно уточняет взаимодействие с классом: все свойства сосредоточены в одном Get/Set методе.

 

Vasiliy Sokolov:

+
 
Vasiliy Sokolov:

1. Тогда тем более используйте стандартную библиотеку, т.к. 95% функций которые Вам нужны, уже скорее всего написаны, многократно отлажены, оптимизированы и опробированы сотнями пользователей. Нет ничего легче, чем написать: ListInfo.Add(new CInfo()); на задумываясь о всяком там выделении/удалении памяти, переразметки массивов и прочей там ерунде. Не в 80-ых годах живем, все-таки. 

2. Перефразирую: если программа включает в себя сотни неструктурированных, разбросанных по разным mqh файлам функций, если не понятно, какие функции за какие классы задач отвечают, то как всем этим управлять и развивать проект? Т.е. Ваше утверждение относится в первую очередь именно к процедурному а не ООП программированию. В ООП-проектах с этим намного лучше, хотя бы потому что существенная (зачастую большая) часть методов реализована в секции private и не доступна для вызовов.

3. IntelliSense рулит. 

ListInfo.Add(new CInfo()); не сложно написать. Как потом будете обращаться к одному элементу? Вот тут сэкономив один раз проигрываешь в дальнейшем много раз.

Изначальный вопрос темы подразумевает, что в массив нужно отправить не просто конкретный класс, а выбрать какой-то из нескольких, иначе нет смысла в функции. Т.е. очень вероятно, что у автора темы имеется родительский класс и несколько дочерних, в функции выполняется выбор дочернего класса. Если без функции, то объявляем массив с типом родительского класса, в него не сложнее отправить объект, чем используя CArrayObj (может получится и сэкономить на ресайзе массива). Аналогично, если использовать стандартный CArrayObj, все равно стоит задача с функцией. Потому-что задача с функцией изначально стоит, может какой сложный выбор дочерних объектов, и автор темы решил сделать его в отдельной функции.

Отсутствие необходимости удалять объекты по завершению работы, это конечно огромный плюс, хотя, с другой стороны, не проблема и самому удалить, если будет выигрыш по другим моментам.

Против стандартных классов никогда не выступал, а наоборот, активно их использую, не надо на меня катить бочку. Вот что интересно, когда сам рекомендовал здесь использовать стандартные классы, мне сразу объясняли, что собственные классы непосредственно заточенные под задачу лучше, а стандартные это сплошные недостатки.

Сотни методов. Пусть не сотни, а десятки, и я не про свое (а вы все только и ищите повода высказаться про неправильное проектирование). У CArrayObj 45 методов, значит каждый раз, имея дело с объектом, перед глазами будет болтаться этот список, в который добавится несколько собственных метода. C# тоже знаете, там как вывалится списочег методов...

 
Dmitry Fedoseev:

ListInfo.Add(new CInfo()); не сложно написать. Как потом будете обращаться к одному элементу? Вот тут сэкономив один раз проигрываешь в дальнейшем много раз.

Обращение к произвольному элементу происходит также элементарно как и в классическом массиве, например: ListInfo.At(23) - обращение к 23 элементу;

Dmitry Fedoseev:

ListInfo.Add(new CInfo()); не сложно написать. Как потом будете обращаться к одному элементу? Вот тут сэкономив один раз проигрываешь в дальнейшем много раз.

Изначальный вопрос темы подразумевает, что в массив нужно отправить не просто конкретный класс, а выбрать какой-то из нескольких, иначе нет смысла в функции. Т.е. очень вероятно, что у автора темы имеется родительский класс и несколько дочерних, в функции выполняется выбор дочернего класса. Если без функции, то объявляем массив с типом родительского класса, в него не сложнее отправить объект, чем используя CArrayObj (может получится и сэкономить на ресайзе массива). Аналогично, если использовать стандартный CArrayObj, все равно стоит задача с функцией. Потому-что задача с функцией изначально стоит, может какой сложный выбор дочерних объектов, и автор темы решил сделать его в отдельной функции.

Сотни методов. Пусть не сотни, а десятки, и я не про свое (а выСотни методов. Пусть не сотни, а десятки, и я не про свое (а вы все только и ищите повода высказаться про неправильное проектирование). У CArrayObj 45 методов, значит каждый раз, имея дело с объектом, перед глазами будет болтаться этот список, в который добавится несколько собственных метода. C# тоже знаете, там как вывалится списочег методов... 

У CArrayObj только 30 публичных методов. Но на то он и контейнер: ведь по мимо функций хранения, он предоставляет функции вставки, удаления и поиска элементов - с помощью которых и должны решаться задачи классификации, предложенные Вами.

Каждый раз, имея дело с объектом, Вы имеете дело не с CArrayObj, а с CObject, который обладает всего 8 методами. Соглашусь, и это слишком много. Но к сожалению из-за отсутствия интерфейсов, приходится тащить начиная с базового CObject специальные указатели  Next, Prev и плюс во многом бесполезные Save и Load методы.

Dmitry Fedoseev:

Отсутствие необходимости удалять объекты по завершению работы, это конечно огромный плюс, хотя, с другой стороны, не проблема и самому удалить, если будет выигрыш по другим моментам.

Против стандартных классов никогда не выступал, а наоборот, активно их использую, не надо на меня катить бочку. Вот что интересно, когда сам рекомендовал здесь использовать стандартные классы, мне сразу объясняли, что собственные классы непосредственно заточенные под задачу лучше, а стандартные это сплошные недостатки.

Вот здесь очень спорно. Каждая выполняемая операция обладает определенной алгоритмической сложностью, которую нельзя снизит. Дядя Кнут подсчитал какие алгоритмы за сколько шагов в лучшем случае могут выполнится - и ни какие языки программирования, а тем более алгоритмы, эти ограничения обойти не могут. Например, удаление элемента из массива, подразумевает его переразметку, что в свою очередь очень негативно сказывается на производительности. И не имеет значения, удаляете Вы элемент из CArrayObj или классического массива, все равно конечной процедурой удаления будет ArrayResize со всеми вытекающими. Да, в каких-то определенных задачах, кастомные решения могут оказаться быстрее, но, опять-таки, не много обогнав в одном месте, Вы на своем костыле неизбежно потеряете в других местах: где-то сделаете поиск не оптимальный, где-то выделите не то количество памяти и т.д. В итоге, время на разработку потратите больше, а производительность в лучшем случае будет такая же.

 
Vasiliy Sokolov:

1. Обращение к произвольному элементу происходит также элементарно как и в классическом массиве, например: ListInfo.At(23) - обращение к 23 элементу;

2. У CArrayObj только 30 публичных методов. Но на то он и контейнер: ведь по мимо функций хранения, он предоставляет функции вставки, удаления и поиска элементов - с помощью которых и должны решаться задачи классификации, предложенные Вами.

3. Каждый раз, имея дело с объектом, Вы имеете дело не с CArrayObj, а с CObject, который обладает всего 8 методами. Соглашусь, и это слишком много. Но к сожалению из-за отсутствия интерфейсов, приходится тащить начиная с базового CObject специальные указатели  Next, Prev и плюс во многом бесполезные Save и Load методы.

4. Вот здесь очень спорно. Каждая выполняемая операция обладает определенной алгоритмической сложностью, которую нельзя снизит. Дядя Кнут подсчитал какие алгоритмы за сколько шагов в лучшем случае могут выполнится - и ни какие языки программирования, а тем более алгоритмы, эти ограничения обойти не могут. Например, удаление элемента из массива, подразумевает его переразметку, что в свою очередь очень негативно сказывается на производительности. И не имеет значения, удаляете Вы элемент из CArrayObj или классического массива, все равно конечной процедурой удаления будет ArrayResize со всеми вытекающими. Да, в каких-то определенных задачах, кастомные решения могут оказаться быстрее, но, опять-таки, не много обогнав в одном месте, Вы на своем костыле неизбежно потеряете в других местах: где-то сделаете поиск не оптимальный, где-то выделите не то количество памяти и т.д. В итоге, время на разработку потратите больше, а производительность в лучшем случае будет такая же.

1. Дальше как? Как вызывать метод собственного объекта? ListInfo.At(23), а дальше? Допустим, в классе CInfo есть метод "method", как его вызывать? Прямо не получается - ListInfo.At(23).method(). Через переменную? Лишние телодвижения, каждый раз, когда надо что-то сделать. 

2. Ровно 45 насчитал. 

3. Да. Всего 8 в нагрузку. Ничего, терпимо.

4. Один ресайз на 10, проще чем 10 ресайзов по 1. Почему костыли? Обычный процесс программирования.

На одном конце весов переменная необходимая для вызова методов, на другом конце необходимость удаления объектов при завершении работы. Кому как нравится.

 
Dmitry Fedoseev:

1. Дальше как? Как вызывать метод собственного объекта? ListInfo.At(23), а дальше? Допустим, в классе CInfo есть метод "method", как его вызывать? Прямо не получается - ListInfo.At(23).method(). Через переменную? Лишние телодвижения, каждый раз, когда надо что-то сделать. 


В спор не лезу (верю и считаю, что полезно уметь и знать все возможности, включая стандартную библиотеку, а применять их адекватно задаче), но так:

#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>

class CInfo : public CObject
{
public:
        string symbol;
        ENUM_TIMEFRAMES timeframe;
        MqlRates rates[];

        // --- Конструктор и деструктор
        CInfo(void)
        {
        };

        CInfo(string symb)
        {
                this.symbol = symb;
        }

        ~CInfo(void)
        {
                Print(symbol, " ", EnumToString(timeframe));
        };

        void SomeMethod(const int x)
        {
                Alert(x);
        };

};

void OnStart()
{
        CArrayObj ListInfo;
        // Добавляем десять элементов типа CInfo
        for (int i = 0; i < 10; i++)
        {
                ListInfo.Add(new CInfo(Symbol()));
        }

        ((CInfo*)ListInfo.At(2)).SomeMethod(111);
}
Причина обращения: