Передача объекта по ссылке

 

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

 Вот есть у меня простой инклюдник, состоящий из 3 структур:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                                                                                                        MarketData.mqh |
//|                                                                                                                                   hoz |
//|                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------+
#ifndef MARKETDATA_H
#define MARKETDATA_H

#property copyright "hoz"
#property link      ""
#property strict
//+=======================================================================================================================================+
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//|                                             СТРУКТУРА ДЛЯ ХРАНЕНИЯ РЫНОЧНОЙ ИНФОРМАЦИИ                                                |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+=======================================================================================================================================+

// =================================================_______ СВОЙСТВА СИМВОЛА _______=======================================================
struct Symbol_Properties
{
   datetime    gdt_Quote;           // Время поступления последней котировки
   double      gda_Price [2];       // Текущие рыночные цены (0 - Bid, 1- Ask)
   double      gd_Spread;           // Размер спреда в пунктах
   double      gd_Swap;             // Своп
   double      gd_Comission;        // Комиссия
   double      gd_Pt;               // Величина одного пункта
   int         gi_Digits;           // Количество знаков в цене после запятой
   int         gi_StopLevel;        // Минимально-допустимый уровень стоп-лосса/тейк-профита в пунктах
   int         gi_FreezLevel;       // Уровень заморозки ордеров в пунктах
};
//---- Создадим объект структуре Symbol_Properties
//Symbol_Properties SSym;

// =================================================_______ СВОЙСТВА ПОЗИЦИИ _______=======================================================
struct Position_Properties
{
   datetime    gdt_Expiration;      // Срок истечения отложенного ордера
   datetime    gdt_OpenTime;        // Время открытия выбранной позиции
   double      gd_OpenPrice;        // Цена открытия
   double      gd_Lots;             // Объём позиции на открытие
   double      gd_CurSL;            // Текущий Stop Loss выбранной позиции
   double      gd_NewSL;            // Новый Stop Loss выбранной позиции
   double      gd_CurTP;            // Текущий Take Profit выбранной позиции
   double      gd_NewTP;            // Новый Take Profit выбранной позиции
   int         gi_CurTicket;        // Тикет выбранного ордера
   int         gi_Type;             // Тип торговой операции
   int         gi_Slippage;         // Максимально допустимое отклонение цены для рыночных ордеров
   int         gi_Magic;            // Магический номер
   string      gs_Comment;          // Комментарий
   string      gs_Symbol;           // Наименование фин. инструмента, с которым производится операция
   ulong       gu_Duration;         // Длительность позиции в секундах
};
//---- Создадим объект структуре Position_Properties
//Position_Properties SPos;

// ==============================================_______ СВОЙСТВА ТОРГОВОГО ЛОТА _______===================================================
struct Lots_Properties
{
   double      gd_MinLot;           // Минимальный объём для заключения сделки
   double      gd_MaxLot;           // Максимальный объём для заключения сделки
   double      gd_LotStep;          // Шаг изменения размера лота
   double      gd_LotSize;          // Размер контракта в базовой валюте инструмента
   int         gi_LotDecimal;       // Определяем минимальную разрядность лота
};
//---- Создадим объект структуре Lots_Properties
Lots_Properties SLots;

#endif

 В классе был метод такой:

// 1.1 Получение рыночной информации по выбранному инструменту. ===========================================================================
BaseInfo::GetMarkerInfo (string                 fs_Symbol,       // Торговый инструмент, по которому нужно собрать информацию
                         int                    fi_Ticket = 0)   // Тикет интересующей нас позиции
{
   bool lb_CondON = true;
   //----
   if (fs_Symbol == SPos.gs_Symbol)
   {
      if (fi_Ticket >= 0)
           lb_CondON = false;
   }
   
   if (lb_CondON)
   {
      if (fi_Ticket > 0)
      {
         SPos.gs_Symbol = OrderSymbol();
      }
      else
      {
         SPos.gs_Symbol = fs_Symbol;
      }
      
      if (SPos.gs_Symbol == _Symbol)
      {
         SSym.gi_Digits = _Digits;
         SSym.gd_Pt = _Point;
      }
      else
      {
         SSym.gi_Digits = (int) MarketInfo (fs_Symbol, MODE_DIGITS);
         SSym.gd_Pt = MarketInfo (fs_Symbol, MODE_POINT);
      }
      
      if (SSym.gd_Pt == 0.0)
          SSym.gd_Pt = GetPoint (fs_Symbol);
   }
   
   if (fi_Ticket > 0)
       GetOrderDetails (fi_Ticket);
   
   //---- Получение текущих цен по инструменту
   RefreshRates();
   SSym.gda_Price [0] = ND (GetTradePrice (0, RealTrade, SPos.gs_Symbol));
   SSym.gda_Price [1] = ND (GetTradePrice (1, RealTrade, SPos.gs_Symbol));
   SSym.gd_Spread = ND (SSym.gda_Price [1] - SSym.gda_Price [0]);
   //----
}

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

BaseInfo::GetMarkerInfo (string                 fs_Symbol,       // Торговый инструмент, по которому нужно собрать информацию
                         Symbol_Properties&     SSym,            // Объект указывающий на структуру свойств позиции
                         Position_Properties&   SPos,            // Ссылка на объект свойств позиции
                         int                    fi_Ticket = 0)   // Тикет интересующей нас позиции

Вызываю её в конструкторе так:

GetMarkerInfo (_Symbol, Symbol_Properties& SSym, Position_Properties& SPos, -1);

 В конструкторе же в этой строке при компиляции вылазит ошибка:

'&' - unexpected token  BaseInfo.mqh    78      45
'&' - unexpected token  BaseInfo.mqh    78      45
'Position_Properties' - invalid cast operation  BaseInfo.mqh    78      53
'&' - unexpected token  BaseInfo.mqh    78      72
'&' - unexpected token  BaseInfo.mqh    78      72
'SPos' - undeclared identifier  BaseInfo.mqh    78      74
'SPos' - parameter conversion not allowed       BaseInfo.mqh    78      74

 Почему? Ведь объект то я передаю получается. Неужели как-то иначе это делается?

 

1. А вы не пробовали почитать инструкции: что, как, для чего, когда лучше, как чаще, чем плохо или не удобно?

2.  GetMarkerInfo (_Symbol, Symbol_Properties& SSym, Position_Properties& SPos, -1);

по ссылке передают уже созданные объекты, что вы тут пытаетесь сделать - какая-то ересь.

создайте объекты отдельно и передайте в функцию по ссылке: 

Symbol_Properties SSym;
Position_Properties& SPos;
GetMarkerInfo (_Symbol, SSym, SPos, -1);

если хотели создать объект при вызове функции тогда так: 

GetMarkerInfo (_Symbol, Symbol_Properties SSym(), Position_Properties SPos(), -1);

не в курсе или в mql корректно все будет обработано, посмотрите сами. 

3. У вас не закоментировано в первом коде Lots_Properties SLots; в  самом конце (2 строчка снизу) это так и надо ?

 
ALXIMIKS:

1. А вы не пробовали почитать инструкции: что, как, для чего, когда лучше, как чаще, чем плохо или не удобно?

Пробывал и читал. Но я когда читал, думал о передаче самого класса почему-то, а не его объекта.


ALXIMIKS:

по ссылке передают уже созданные объекты, что вы тут пытаетесь сделать - какая-то ересь.

создайте объекты отдельно и передайте в функцию по ссылке: 

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

 

ALXIMIKS:

если хотели создать объект при вызове функции тогда так: 

Symbol_Properties SSym;
Position_Properties& SPos;
GetMarkerInfo (_Symbol, SSym, SPos, -1);

  

Возможно, Вы имеете в виду так:

Symbol_Properties& SSym;
Position_Properties& SPos;
GetMarkerInfo (_Symbol, SSym, SPos, -1);

 Получается, разумнее было бы в инклюднике сразу создавать со знаком & все объекты?

 

3. У вас не закоментировано в первом коде Lots_Properties SLots; в  самом конце (2 строчка снизу) это так и надо ?

 Ну по началу были раскомментированы все созданные объекты. Потому я решил раскоментить по очерёдно, чтоб передать их по ссылке. До Lots_Properties SLots не добрался... Уже этот момент я понял.
 

Можно не созданный передавать. Только добавить *.

xxx * & yyy

 
Integer:

Можно не созданный передавать. Только добавить *.

xxx * & yyy

 

 

 


 Но это уже указатель. И разыменование. Прироста производительности не достигнется. Т.к. это не ссылка. 

 
Symbol_Properties SSym;
Position_Properties& SPos;
GetMarkerInfo (_Symbol, SSym, SPos, -1);

извините, это я опечатался немного - недоудалил &.


Ссылка это как псевдоним у писателей:

1. Мы купили кота, назвали его Вася. (то же самое что создали объект класса Сat:  Сat Baca; )

2.  Задача кота уметь кушать и гадить ( то же что и методы класса)

3. Если мы начнем кота называть не Вася, а Василий ( эквивалент Сat& Bacilij = Baca;)

4. То мы все еще будем иметь лишь одного кота но с двумя кличками.

5. Если же побрить налысо  Василия, то как бы не хотелось, Вася тоже пострадает (ведь это один и тот же кот: Bacilij  = 0; if (Baca == 0) ; // true)

6. И на оборот - если Васе дать обожраться, то и у Bасилия будет болеть живот.

как то так.

 
hoz:


 Но это уже указатель. И разыменование. Прироста производительности не достигнется. Т.к. это не ссылка. 


в с++ указатель и ссылка грубо говоря одно и тоже (ссылка - это неявно разъименованый указатель +- свои приколы).

тут же, в mql нас от чего то спасают, что-то запрещают, и постоянна страхуют от падения.

 
hoz:


 Но это уже указатель. И разыменование. Прироста производительности не достигнется. Т.к. это не ссылка. 


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

 

 Всё то оно хорошо, но воз и ныне там. Есть структура:

// =================================================_______ СВОЙСТВА СИМВОЛА _______=======================================================
struct Symbol_Properties
{
   datetime    gdt_Quote;           // Время поступления последней котировки
   double      gda_Price [2];       // Текущие рыночные цены (0 - Bid, 1- Ask)
   double      gd_Spread;           // Размер спреда в пунктах
   double      gd_Swap;             // Своп
   double      gd_Comission;        // Комиссия
   double      gd_Pt;               // Величина одного пункта
   int         gi_Digits;           // Количество знаков в цене после запятой
   int         gi_StopLevel;        // Минимально-допустимый уровень стоп-лосса/тейк-профита в пунктах
   int         gi_FreezLevel;       // Уровень заморозки ордеров в пунктах
};
//---- Создадим объект структуре Symbol_Properties
Symbol_Properties SSym;

 В ней я сразу создаю объект структуре, чтоб не плодить дубликаты и использовать его во всех зависимых классах. Это ведь логично? Или как-то иначе делать можно?

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

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

 

Почему я спрашиваю... Вот пример из учебника Стивена Прата, который пишет именно так как я написал в первом своём сообщении:

 

 

 

 Получается я ещё сразу делал верно. Но почему-то это не работает тут. Или кто-то со мной не согласен? Что ещё нужно сделать чтоб не ругался компилятор?

В приведённом примере из учебника Стивена Прата чётко видно, что с самого начала написана структура. А дальше не создавался объект. После чего в параметре функции происходит ссылка на объект структуры. Почему так?

 И вообще как мне быть в моём случает? 

 
 
hoz:

...

В приведённом примере из учебника Стивена Прата чётко видно, что с самого начала написана структура. А дальше не создавался объект. После чего в параметре функции происходит ссылка на объект структуры. Почему так?

В параметрах не происходит никаких ссылок, в параметрах описывается, какие параметры должны передаваться функции и каким образом. В данном случае  в функцию display передается параметр типа free_trow по ссылке.

Так где написано "Создаем структуру", она не создается, а описывается.

Чтобы передавать в функцию, надо будет создать (объявить) переменную типа free_throw, а потом передавать ее.