В частности, я уже не раз показывал, как у меня организован доступ к истории или к позиции - ты получаешь виртуальный интерфейс, в котором одни функции. Внутренняя реализация - полностью скрыта. Именно инкапсуляция ООП это и позволяет. Без ООП такую инкапсуляцию сделать не выйдет.
Такой код будет нечитаемым и баги в нем замучаешься ловить. Причем создается проблема на ровном месте, так как логически он ничего не делает.
И в чем проблема передать массив по ссылке в функцию?
Это когда тебе надо в одну функцию передать один массив.
А вот когда у тебя вложенность превышает десяток, в каждой функции из этих "матрешек" требуются какие-то данные, а массивы не нужны, а массивы понадобятся на самом "глубоком" уровне - то тебе придется передавать массивы по ссылкам внутрь всех этих функция-"матрешек", И тащить все это будет весьма напряжно.
С классом же - ты получаешь указатель, сохраняешь его внутри класса, и лишь на самом глубоком уровне - обращаешься к массиву, используя указатель.
Такой код будет нечитаемым и баги в нем замучаешься ловить. Причем создается проблема на ровном месте, так как логически он ничего не делает.
Он будет никак не менее читаемым, чем код в "функциональном" стиле с массой ifdef'ов.
Никакой проблемы не создается - написать-то можно и так, и так. Но вот когда потребуется отладка, или, особенно, модификация - ООП-подход дает очень существенные плюсы.
Если ты-монстр запоминания - то вобще, можно все данные свалить в один огромный глобально доступный массив, и работать с ним. Но, большинство народа уже через неделю, как правило, забывают тонкости, с которыми пришлось работать на том или ином участке кода, и как раз жестко заданные интерфейсы, полная инкапсуляция, запрет на доступ к любым данным, кроме тех, которые тебе необходимы на данном участке кода - позволяет избежать очень многих ошибок.
С указателями давно уже никто не работает со времен С, это плохой стиль ибо код будет невозможно отлаживать.
Всегда работаю ТОЛЬКО с указателями. Код прекрасно отлаживается.
Интересно, как ты собираешься работать без указателей, если оператор new возвращает именно указатель ?
Плохой ли это стиль ? Ну не знаю... Я не раз уже показывал свои функции...
Допустим, вот функция класса CDataProviderT (провайдер данных), которая создает указанную таймсерию по ее типу, символу, таймфрейму, с нужным размером:
CSeriesI* CDataProviderT::_CreateSeries(EAllSeries asSeriesType,ECurrencySymbol csSymbol,ENUM_TIMEFRAMES etTimeframe,uint uiSize)
{
CTimeSeriesT* ptscResult = NULL;
switch(asSeriesType)
{
case AS_OPEN:
ptscResult = new CTSOpen;
break;
case AS_HIGH:
ptscResult = new CTSHigh;
break;
case AS_LOW:
ptscResult = new CTSLow;
break;
case AS_CLOSE:
ptscResult = new CTSClose;
break;
case AS_SPREAD:
ptscResult = new CTSSpread(GetConstSpread(csSymbol));
break;
case AS_TIME:
ptscResult = new CTSTime;
break;
case AS_TICK_VOLUME:
ptscResult = new CTSVolume(true);
break;
case AS_REAL_VOLUME:
ptscResult = new CTSVolume(false);
break;
default:
ASSERT(false);
return(NULL);
};
if(ptscResult == NULL)
{
ASSERT_DSC(false,"Не удалось создать таймсерию");
return(NULL);
};
if(ptscResult.Init(csSymbol,etTimeframe,uiSize)==false)
{
ASSERT_DSC(false,"Не удалось инициализировать таймсерию");
delete ptscResult;
return(NULL);
};
if(m_aoTimeSeries.Add(ptscResult) == false)
{
ASSERT_DSC(false,"Не удалось присоединить таймсерию к списку");
delete ptscResult;
return(NULL);
};
return(ptscResult);
};
В зависимости от типа таймсерии мы создаем нужную таймсерию по new, если вернулся нулевой указатель - значит, была ошибка, возвращаем код. Если указатель вернулся валидный - то инициализируем его. В случае, если инициализация вернула ошибку - удаляем созданный объект, и возвращаем признак ошибки. Если инициализация прошла успешно - добавляем указатель на таймсерию в массив объектов-таймсерий.
Таким образом, в дата-провайдере мы имеем массив, в котором лежат все таймсерии, использующиеся в ТС. Есть возможность работы сразу нескольких ТС в рамках одного эксперта - каждая будет обращаться к дата-провайдеру за таймсериями, а дата-провайдер, как раз поглядит, есть ли в массиве указателей нужная таймсерия, и если есть - возвратит ее, не создавая заново.
Как раз чтобы помнить все интерфейсы где они что скрывают, куда ведут и зачем и надо быть монстром.)
Интересно-интересно.
Я уже не раз показывал, вот интерфейс торговой позиции:
class CTradePositionI: public CMyObject
{
public:
// Выбор существующей позиции. // Указывается магик и символ, по которому выбираются действующие ордера.// Если ulMagic = 0 - выбираются все позиции по всем магикам.// Если ECurrencySymbol = CS_UNKNOWN - выбираются все позиции по всем символам// Если ECurrencySymbol = CS_CURRENT - запрашивается функция Symbol(), и выбираются все позиции по этому символу// Возвращает число компонент позиции внутри позиции (может быть нулевым если позиции нет) или WRONG_VALUE в случае ошибок// Каждая фабрика (наследник CEAPartsFactoryT) имеет одну позицию, которая на каждом CEAPartsFactoryT::OnRefresh()// обновляется в соответствии с магиком и рабочим символом фабрики. virtualint Select(ulong ulMagic = 0,ECurrencySymbol csSymbol = CS_CURRENT) = 0;
virtualuint GetTotalComponents() const = 0; // Получение общего числа компонентvirtual CTradePosComponentI* GetComponent(uint uiComponentIdx) const = 0;
};
Вызываем Select(), а потом можем запросить общее число компонент, и каждую компоненту в отдельности.
ЧТО в данном интерфейсе - тебе надо "запоминать" ? Ты физически не можешь сделать ничего другого, кроме как выбрать позицию, и перебрать открытые ее компоненты. В функции - ты тоже сунуться не можешь, они приравнены нулю, чисто виртуальны. Но в отладчике - это возможно.
А по-твоему, ты должен здесь что-то запомнить, чтобы не перепутать ? Что ?
Например, передать любое количество массивов в функцию в процедурном стиле не получится.
То есть передать в функцию переменное количество массивов? Такой код будет невозможно отлажить.
Да ну ???
Попробуй возможность не копировать массив, а передавать адрес - дорого стоит.
И в чем проблема передать массив по ссылке в функцию?
Georgiy Merts:
В частности, я уже не раз показывал, как у меня организован доступ к истории или к позиции - ты получаешь виртуальный интерфейс, в котором одни функции. Внутренняя реализация - полностью скрыта. Именно инкапсуляция ООП это и позволяет. Без ООП такую инкапсуляцию сделать не выйдет.
Такой код будет нечитаемым и баги в нем замучаешься ловить. Причем создается проблема на ровном месте, так как логически он ничего не делает.
И в чем проблема передать массив по ссылке в функцию?
Это когда тебе надо в одну функцию передать один массив.
А вот когда у тебя вложенность превышает десяток, в каждой функции из этих "матрешек" требуются какие-то данные, а массивы не нужны, а массивы понадобятся на самом "глубоком" уровне - то тебе придется передавать массивы по ссылкам внутрь всех этих функция-"матрешек", И тащить все это будет весьма напряжно.
С классом же - ты получаешь указатель, сохраняешь его внутри класса, и лишь на самом глубоком уровне - обращаешься к массиву, используя указатель.
С классом же - ты получаешь указатель, сохраняешь его внутри класса, и лишь на самом глубоком уровне - обращаешься к массиву, используя указатель.
С указателями давно уже никто не работает со времен С, это плохой стиль ибо код будет невозможно отлаживать.
Такой код будет нечитаемым и баги в нем замучаешься ловить. Причем создается проблема на ровном месте, так как логически он ничего не делает.
Он будет никак не менее читаемым, чем код в "функциональном" стиле с массой ifdef'ов.
Никакой проблемы не создается - написать-то можно и так, и так. Но вот когда потребуется отладка, или, особенно, модификация - ООП-подход дает очень существенные плюсы.
Если ты-монстр запоминания - то вобще, можно все данные свалить в один огромный глобально доступный массив, и работать с ним. Но, большинство народа уже через неделю, как правило, забывают тонкости, с которыми пришлось работать на том или ином участке кода, и как раз жестко заданные интерфейсы, полная инкапсуляция, запрет на доступ к любым данным, кроме тех, которые тебе необходимы на данном участке кода - позволяет избежать очень многих ошибок.
Georgiy Merts:
Если ты-монстр запоминания - то вобще, можно все данные свалить в один огромный глобально доступный массив
Как раз чтобы помнить все интерфейсы где они что скрывают, куда ведут и зачем и надо быть монстром.)
С указателями давно уже никто не работает со времен С, это плохой стиль ибо код будет невозможно отлаживать.
Всегда работаю ТОЛЬКО с указателями. Код прекрасно отлаживается.
Интересно, как ты собираешься работать без указателей, если оператор new возвращает именно указатель ?
Плохой ли это стиль ? Ну не знаю... Я не раз уже показывал свои функции...
Допустим, вот функция класса CDataProviderT (провайдер данных), которая создает указанную таймсерию по ее типу, символу, таймфрейму, с нужным размером:
В зависимости от типа таймсерии мы создаем нужную таймсерию по new, если вернулся нулевой указатель - значит, была ошибка, возвращаем код. Если указатель вернулся валидный - то инициализируем его. В случае, если инициализация вернула ошибку - удаляем созданный объект, и возвращаем признак ошибки. Если инициализация прошла успешно - добавляем указатель на таймсерию в массив объектов-таймсерий.
Таким образом, в дата-провайдере мы имеем массив, в котором лежат все таймсерии, использующиеся в ТС. Есть возможность работы сразу нескольких ТС в рамках одного эксперта - каждая будет обращаться к дата-провайдеру за таймсериями, а дата-провайдер, как раз поглядит, есть ли в массиве указателей нужная таймсерия, и если есть - возвратит ее, не создавая заново.
Как подобное сделать без указателей ?
Да и отладка этого кода - не такая уж мудреная...
Как раз чтобы помнить все интерфейсы где они что скрывают, куда ведут и зачем и надо быть монстром.)
Интересно-интересно.
Я уже не раз показывал, вот интерфейс торговой позиции:
Вызываем Select(), а потом можем запросить общее число компонент, и каждую компоненту в отдельности.
ЧТО в данном интерфейсе - тебе надо "запоминать" ? Ты физически не можешь сделать ничего другого, кроме как выбрать позицию, и перебрать открытые ее компоненты. В функции - ты тоже сунуться не можешь, они приравнены нулю, чисто виртуальны. Но в отладчике - это возможно.
А по-твоему, ты должен здесь что-то запомнить, чтобы не перепутать ? Что ?