Особенности языка mql5, тонкости и приёмы работы - страница 282

 
Artyom Trishkin #:

А есть способ узнать историю без ковыряния в истории? Подскажи.

Это секрет…)

 
Vladislav Boyko #:

Разве '&a' не означает 'GetPointer(a)' ? А дальше неявный operator= принимает ссылку.

  1. reference (автоматический объект изначально) -->
  2. pointer (как результат &) -->
  3. reference (указатель преобразован компилятором в ссылку для передачи в operator=(const A&))
Могу ошибаться, я не проверял, но на первый взгляд ваш код должен работать именно так, как я описал

Именно так и работает.

 
fxsaber #:

Именно так и работает.

Не могу понять смысл 'a = &a' для того конкретного примера. Почему не заменить на 'a = a' ?

[edit]

В случае с двумя указателями я бы явно вызвал оператор operator= на всякий случай😅

class A {};

void OnStart()
  {
   A* a1;
   A* a2;
   a1.operator=(a2);
  }
Хотя, с двумя указателями это наверное единственный способ вызова operator=
 
Vladislav Boyko #:

Не могу понять смысл 'a = &a' для того конкретного примера. Почему не заменить на 'a = a' ?

Пример.
#define SIZE 200

class A
{
private:
  double Array[SIZE];
  
public:
  double operator []( const int Pos ) const
  {
    return(this.Array[Pos]);
  }
};

void OnStart()
{
  double Sum = 0;

  A a1, a2;
  A* a = new A;  

  A b = a; // Аналогия a = &a;
//  #define a b // Ускорение.
   
  const ulong StartTime = GetMicrosecondCount();
  
  for (int i = 0; i < 1e7; i++)
    Sum += a[i % SIZE] + a1[i % SIZE] + a2[i % SIZE]; 
    
  Print((string)(GetMicrosecondCount() - StartTime) + " mcs.");

  #undef a
    
  delete a;
}
 
Vladislav Boyko #:

В случае с двумя указателями я бы явно вызвал оператор operator= на всякий случай😅

Хотя, с двумя указателями это наверное единственный способ вызова operator=

Да.

class A
{
public:  
  void operator =( const A* ) { Print(__FUNCSIG__); }
};

void OnStart()
{
  A* a = new A;
  
  a = a; 	  // Хорошо, что не принтует.
  a.operator=(a); // Принтует, как надо.
  
  delete a;
}
 
fxsaber #:
Пример.

Я понял. Я бы наверное предпочел в метод обернуть. Хотя этот конкретный сомнительный тест показывает, что ваш вариант с копированием объекта немного быстрее.

#define SIZE 200

class A
{
private:
  double      Array[SIZE];
public:
              A() { for(int i = 0; i < SIZE; i++) Array[i] = 1.0 / (i + 1); }
  double      operator []( const int Pos ) const { return(this.Array[Pos]); }
  static void test1();
  static void test2(const A& a, const A& a1, const A& a2);
};

void OnStart()
  {
   A::test1();
   //---
   A a1, a2;
   A* a = new A;
   A::test2(a, a1, a2);
   delete a;
  }

void A::test2(const A &b,const A &a1,const A &a2)
  {
   double Sum = 0;
   const ulong StartTime = GetMicrosecondCount();
   for (int i = 0; i < 1e7; i++)
      Sum += b[i % SIZE] + a1[i % SIZE] + a2[i % SIZE]; 
   PrintFormat(__FUNCTION__" %I64i mcs, sum %f", GetMicrosecondCount() - StartTime, Sum);
  }

void A::test1(void)
  {
   double Sum = 0;
   A a1, a2;
   A* a = new A;  
   A b = a;
   const ulong StartTime = GetMicrosecondCount();
   for (int i = 0; i < 1e7; i++)
      Sum += b[i % SIZE] + a1[i % SIZE] + a2[i % SIZE]; 
   PrintFormat(__FUNCTION__" %I64i mcs, sum %f", GetMicrosecondCount() - StartTime, Sum);
   delete a;
  }
 
Vladislav Boyko #:

Я бы наверное предпочел в метод обернуть.

Специально добавил a1/a2, чтобы показать, что обернуть в метод иногда бывает почти невозможно - слишком искусственно при сложном ветвлении внутри for из разных локальных переменных.

 

Vladislav Boyko #:

reference (указатель преобразован компилятором в ссылку для передачи в operator=(const A&))

Так можно увидеть его присутствие/сигнатуру.

class A {};

A a = NULL;
'NULL' - parameter conversion not allowed
   void A::operator=(const A&)
'operator=' - object required
2 errors, 0 warnings
 
fxsaber #:

Так можно увидеть его присутствие/сигнатуру.

Это все хорошо, но до первого константного поля. Наверное, лучше добавить явный конструктор копирования и использовать его. Но в MQL есть 2 недостатка касаемо конструкторов копирования:

  1. компилятор не генерирует неявный конструктор копирования

https://www.mql5.com/ru/docs/basis/types/classes#class

В случае если явно определен конструктор, инициализация переменной типа структуры или класса при помощи инициализирующей последовательности невозможна.

 
Vladislav Boyko #:

Это все хорошо, но до первого константного поля. Наверное, лучше добавить явный конструктор копирования и использовать его. Но в MQL есть 2 недостатка касаемо конструкторов копирования:

  1. компилятор не генерирует неявный конструктор копирования

Не понял.