Вопросы по ООП (Объектно Ориентированному Программированию ) - страница 11

 

 Хотелось бы узнать мнение более опытных программистов касательно некоторых нюансов. Вот взять хотя бы объявления переменных в классах. Есть, например, у меня в классах переменные, которые объявляются внутри различных методов данного канкретного класса. Объявляются они в каждом методе чаще всего. Стоит ли так делать или лучше объявить один раз в секции private и потом пользоваться ей?

 Я так понимаю переменные счётчиков так логичнее будет использовать, если они в циклах, так? Ведь счётчик явно задаётся значением в момент рассчёта, например, если использовать цикл:

for (i = OrdersTotal() - 1; i >= 0; i--)
{

}

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

Так же касательно не только циклов, но и других вариантов. Ведь хватает различных переменных, которые приходится объявлять ни один раз, но играющие ту же самую роль.. Единственное, как я вижу, некоторые придётся обнулять в значении, чтоб не было в них "мусора" от предыдущих операции. Тогда резонно ли это делать или проще заново объявить подобную переменную... В общем хочется услышать об этом от профессионалов.

 
hoz:

 Хотелось бы узнать мнение более опытных программистов касательно некоторых нюансов. Вот взять хотя бы объявления переменных в классах. Есть, например, у меня в классах переменные, которые объявляются внутри различных методов данного канкретного класса. Объявляются они в каждом методе чаще всего. Стоит ли так делать или лучше объявить один раз в секции private и потом пользоваться ей?

 Я так понимаю переменные счётчиков так логичнее будет использовать, если они в циклах, так? Ведь счётчик явно задаётся значением в момент рассчёта, например, если использовать цикл:

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

Так же касательно не только циклов, но и других вариантов. Ведь хватает различных переменных, которые приходится объявлять ни один раз, но играющие ту же самую роль.. Единственное, как я вижу, некоторые придётся обнулять в значении, чтоб не было в них "мусора" от предыдущих операции. Тогда резонно ли это делать или проще заново объявить подобную переменную... В общем хочется услышать об этом от профессионалов.

 

 

Стоит ли так делать - зависит от цели, для которой заводится переменная. Если класс инкапсулирует какую-нибудь сущность, например, ордер, то для выражения его свойств, например, тикета ордера, потребуются переменные, определённые в классе. Эти переменные будут общими для всех методов данного класса для одного и того же объекта этого класса.

Если же переменная заводится для организации цикла внутри какого-то метода, то она должна быть определена внутри метода как автоматическая (то есть, без использования ключевого слова static). В этом случае даже если один метод вызывает изнутри своего цикла другой метод, в котором также организован цикл, и используется переменная с тем же именем, то никаких проблем не возникнет. При использовании же переменной, объявленной в классе, переменная будет перезаписана в цикле второго метода.

Для автоматических переменных память выделяется автоматически при входе в функцию и автоматически же удаляется при выходе, причём, с минимальными накладными расходами. Более того, если функции простые, компилятор может генерировать такой код, в котором вообще не будет специальных действий по выделению и освобождению автоматической памяти.

Экономия ячеек памяти подобного рода когда-то давно ещё могла быть осмысленным занятием, но сие занятие окончательно потеряло смысл лет 20 назад...

 

 Есть класс. У него такой вот простой метод, весь распринтованный до безобразия, т.к. я искал, где косяк:

// 1.5 Определяем минимальную разрядность лота. ===========================================================================================
int BaseInfo::LotPrecision()
{
   static int li_LotPrecision = 0;     // устанавливаем минимальную разрядность лота в ноль
   Print ("LotPrecision()_Before: li_LotPrecision = ", li_LotPrecision);
   Print ("LotPrecision()_BeforeCircle: SLots.gd_LotStep = ", SLots.gd_LotStep);
   while (SLots.gd_LotStep < 1)
   {
      Print ("LotPrecision(): SLots.gd_LotStep < 1");
      SLots.gd_LotStep *= 10;
      Print ("SLots.gd_LotStep *= 10");
      Print ("LotPrecision(): SLots.gd_LotStep = ", SLots.gd_LotStep);
      li_LotPrecision++;
      Print ("LotPrecision(): li_LotPrecision = ", li_LotPrecision);
   }
   Print ("LotPrecision(): LOTPRES = ", li_LotPrecision);
   return (li_LotPrecision);
}

 Переменная li_LotPrecision раньше была без модификатор static, потом я посмотрел, что она не должна терять значение и сменил ей модификатор. Замечено, что хоть я модификатор и добавил, тем не менее данная переменная li_LotPrecision не сохраняет своё значение.

 Принтую в OnInite()

void OnTick()
{
   int Lot = CBase.LotPrecision();
   Print ("Lot = ", Lot);
}

В логе:

17:26:03 2014.07.22 14:10  RSI EURUSD,M5: SLots.gd_LotStep = MarketInfo (_Symbol, MODE_LOTSTEP); = 0.01
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 0.01
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep < 1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: SLots.gd_LotStep *= 10
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep = 0.1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): li_LotPrecision = 1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep < 1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: SLots.gd_LotStep *= 10
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep = 1.0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): li_LotPrecision = 2
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): LOTPRES = 2
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 1.0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): LOTPRES = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: Lot = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 1.0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): LOTPRES = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: Lot = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 1.0

 Тут чётко видно, что после выхода из функции LotPrecision() значение переменной li_LotPrecision теряется. Как сделать так, что оно оставалось постоянным?

Я пробывал добавлять в секцию private класса данную переменную li_LotPrecision, чтоб потом ей модификатор static присвоить, но компилятор ругается, чтоб мол так нельзя.

unresolved static variable 'BaseInfo::li_LotPrecision'  BaseInfo.mqh    60      10

 Выкидывать переменную за пределы класса не резон, т.к. больше нигде она не нужна.

Как быть?

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