Вопрос по массиву - страница 2

 
Georgiy Merts:

А по мне - все эти многомерные массивы - это почва для трудноуловимых ошибок.

Код должен быть простой, как три копейки. 

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

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

Наш лозунг: "ни дня, что бы не трахнуть мозг ближнему своему!"

 
Да, и если кто-то не заметил, в первом посте вопрос про доступ по строковому ключу.
 
Dmitry Fedoseev:

Наш лозунг: "ни дня, что бы не трахнуть мозг ближнему своему!"

Не согласен.

Скажем, историю торговли можно хранить в многомерном массиве. Но при этом - надо все время помнить, какой индекс за что отвечает, где какие типы полей, где массивы.

Куда проще с интерфейсами. У меня это сделано так. Запрашиваешь историю, получаешь интерфейс (для простоты неважное для понимания поубирал):

class CTradeHistoryI
{
   virtual uint GetTotalComponents() const = 0;  // Получение общего числа компонент
   virtual CHistoryPosComponentI* GetComponent(uint uiComponentIdx) const = 0;
}

У тебя есть всего лишь две функции - ты можешь запросить число компонент позиции в истории (компонента позиции - сокращенно TPC -  это ордер для МТ4 или позиция для МТ5), и вызвать интерфейс нужной компоненты.

Вызывав этот интерфейс - ты получаешь следующее:

class CHistoryPosComponentI: public CTradePosComponentI
{
public:
   virtual datetime           GetTPCCloseTime()    const = 0;
   virtual double             GetTPCClosePrice()   const = 0;
   virtual double             GetTPCProfit()       const = 0;  // Возвращает профит по исторической позиции
   
   virtual bool               IsProfitClosePrice() const = 0;   // Возвращает true, если цена зарытия отличается от цены открытия в прибыльную сторону   
   virtual ETPCCloseType      GetCloseType()       const = 0;   // Возвращает тип закрытия компоненты.
};

В этом классе - у каждой компоненты ты можешь запросить данные, относящиеся к истории.

Можно вызвать и функции базового класса, относящиеся как к истории, так и к открытым позициям (поэтому это класс-предок):

class CTradePosComponentI
{
public:
   
   // Основной интерфейс
   virtual long               GetTPCTicket()       const = 0;
   virtual long               GetTPCMagic()        const = 0;
   virtual ECurrencySymbol    GetTPCSymbol()       const = 0;
   virtual ENUM_POSITION_TYPE GetTPCType()         const = 0;
   virtual ENUM_ORDER_TYPE    GetTPCPending()      const = 0; // Для открытых ордеров или позиций - WRONG_VALUE
   virtual datetime           GetTPCOpenTime()     const = 0;
   virtual double             GetTPCVolume()       const = 0;
   virtual double             GetTPCOpenPrice()    const = 0;
   virtual double             GetTPCStopLoss()     const = 0;
   virtual double             GetTPCTakeProfit()   const = 0;
   virtual string             GetTPCCommentary()   const = 0;

}

Каждая функция отвечает лишь за одно поле, и его спутать куда сложнее, чем если бы все эти значения лежали в многомерном массиве.

Причина обращения: