Русский

Справочник MQL4 Общие функции GetPointer

GetPointer

Возвращает указатель объекта.

void*  GetPointer(
   any_class anyobject      // объект любого класса
   );

Параметры

anyobject

[in]  Объект любого класса.

Возвращаемое значение

Возвращает указатель объекта.

Примечание

Только объекты классов имеют указатели. Экземпляры структур и переменные простых типов указателей не имеют. Объект класса, который не создан при помощи оператора new(), а например, автоматически созданный в массиве объектов, все равно имеет указатель. Только этот указатель будет иметь автоматический тип POINTER_AUTOMATIC, и к нему нельзя применить оператор delete(). В остальном указатель типа ничем не отличается от динамических указателей типа POINTER_AUTOMATIC.

Так как переменные типа структур и простых типов не имеют указателей, то применять к ним функцию GetPointer() запрещено. Также запрещается в качества аргумента функции передавать указатель. Во всех перечисленных случаях компилятор сообщит об ошибке.

Попытка к обращения к некорректному указателю приводит к критическому завершению программы. Поэтому существует необходимость использования функции CheckPointer() перед использованием указателя. Указатель может быть некорректным в следующих случаях:

  • указатель равен NULL;
  • если объект был уничтожен при помощи оператора delete.

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

Пример:

//+------------------------------------------------------------------+
//|                                             Check_GetPointer.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
//+------------------------------------------------------------------+
//| Класс, реализующий элемент списка                                |
//+------------------------------------------------------------------+
class CItem
  {
   int               m_id;
   string            m_comment;
   CItem*            m_next;
public:
                     CItem() { m_id=0; m_comment=NULL; m_next=NULL; }
                    ~CItem() { Print("Destructor of ",m_id,
                                     (CheckPointer(GetPointer(this))==POINTER_DYNAMIC)?
                                     "dynamic":"non-dynamic"); }
   void              Initialize(int id,string comm) { m_id=id; m_comment=comm; }
   void              PrintMe() { Print(__FUNCTION__,":",m_id,m_comment); }
   int               Identifier() { return(m_id); }
   CItem*            Next() {return(m_next); }
   void              Next(CItem *item) { m_next=item; }
  };
//+------------------------------------------------------------------+
//| Простейший класс списка                                          |
//+------------------------------------------------------------------+
class CMyList
  {
   CItem*            m_items;
public:
                     CMyList() { m_items=NULL; }
                    ~CMyList() { Destroy(); }
    bool             InsertToBegin(CItem* item);
    void             Destroy();
  };
//+------------------------------------------------------------------+
//| Вставляет элемент списка в самое начало                          |
//+------------------------------------------------------------------+
bool CMyList::InsertToBegin(CItem* item)
  {
   if(CheckPointer(item)==POINTER_INVALIDreturn(false);
//---
   item.Next(m_items);
   m_items=item;
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Уничтожает список через уничтожение элементов                    |
//+------------------------------------------------------------------+
void CMyList::Destroy()
  {
//--- служебный указатель для работы в цикле
   CItem* item;
//--- пройдемся в цикле и попытаемся удалить динамические указатели
   while(CheckPointer(m_items)!=POINTER_INVALID)
     {
      item=m_items;
      m_items=m_items.Next();
      if(CheckPointer(item)==POINTER_DYNAMIC)
        {
         Print("Dynamyc object",item.Identifier(),"to be deleted");
         delete (item);
        }
      else Print("Non-dynamic object",item.Identifier(),"cannot be deleted");
     }
//---
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CMyList list;
   CItem   items[10];
   CItem*  item;
//--- создадим и добавим в список динамический указатель объекта
   item=new CItem;
   if(item!=NULL)
     {
      item.Initialize(100,"dynamic");
      item.PrintMe();
      list.InsertToBegin(item);
     }
//--- добавим автоматические указатели в список
   for(int i=0; i<10; i++)
     {
      items[i].Initialize(i,"automatic");
      items[i].PrintMe();
      item=GetPointer(items[i]);
      if(CheckPointer(item)!=POINTER_INVALID)
         list.InsertToBegin(item);
     }
//--- добавим еще один динамический указатель объекта в начало списка 
   item=new CItem;
   if(item!=NULL)
     {
      item.Initialize(200,"dynamic");
      item.PrintMe();
      list.InsertToBegin(item);
     }
//--- удалим элементы списка
   list.Destroy();
//--- все элементы списка будут уничтожены,
//--- смотри в терминале закладку Experts
  }

Смотри также

Указатели объектов, Проверка указателя объекта, Оператор уничтожения объекта delete