Как изменить элемент массива через оператор "квадратная скобка".

 

Всех приветствую. 

Такой вопрос.

Оператор "квадратная скобка" возможен для получения значения массива. Вот так:

// Внутри объявления класса
int operator[] (int iIdx) { return(...); };

...

// В коде, где надо получить нулевой элемент.
int iNullElement = mуArray[0];

А как надо объявить этот оператор (и можно ли), чтобы устанавливать значения внутри класса?

mуArray[0] = 234;

mуArray[1] = 345;

mуArray[2] = 123;

...

Что-то я так никогда не делал, использовал функции типа Set(iIdx,dValue), а вот как тоже самое сделать с помощью оператора? 

 
Здесь пример смотрели? https://www.mql5.com/ru/docs/basis/function/operationoverload
Документация по MQL5: Основы языка / Функции / Перегрузка операций
Документация по MQL5: Основы языка / Функции / Перегрузка операций
  • www.mql5.com
Перегрузка операций - Функции - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Rashid Umarov #:
Здесь пример смотрели? https://www.mql5.com/ru/docs/basis/function/operationoverload

Вот-вот, как раз хороший пример, и в нем перегрузка оператора "квадратные скобки" и для строки и для матрицы - ВОЗВРАЩАЕТ значение. А хотелось бы УСТАНОВИТЬ значение с помощью такого оператора (использую класс из того же примера):

CRow rMyRow;                       // Объявляем переменную rMyRow типа CRow

.....                              // Здесь инициализируем rMyRow какими-то значениями.

double dFirstElement = rMyRow[1];  // Получаем элемент ряда индекса 1 с помощью оператора "квадратная скобка" - так можно.

rMyRow[0] = 3.1;                   // Устанавливаем элемент ряда индекса 0  с помощью оператора "квадратная скобка" - а так НЕЛЬЗЯ!

Я по-разному пробовал, не выходит. Впечатление такое, что так нельзя. 

Нужно иметь в классе CRow функцию типа

CRow::SetValue(int iIdx,double dValue) { m_array[iIdx] = dValue; }

А как функцию с таким функционалом представить в виде оператора? Это можно?

 
Georgiy Merts #:

Вот-вот, как раз хороший пример, и в нем перегрузка оператора "квадратные скобки" и для строки и для матрицы - ВОЗВРАЩАЕТ значение. А хотелось бы УСТАНОВИТЬ значение с помощью такого оператора (использую класс из того же примера):

Я по-разному пробовал, не выходит. Впечатление такое, что так нельзя. 

Нужно иметь в классе CRow функцию типа

А как функцию с таким функционалом представить в виде оператора? Это можно?

А конструктор с параметрами не поможет?

 

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

 
class A
{
private:
  int Pos;

public:
  double Array[5];
  
  A* operator []( const int iPos )
  {
    this.Pos = iPos;
    
    return(&this);
  }  
  
  void operator =( const double Value )
  {
    this.Array[this.Pos] = Value;
  }
};

void OnStart()
{
  A a;
  
  for (int i = 0; i < 5; i++)
    a[i] = i;
    
  ArrayPrint(a.Array);
}
 
fxsaber #:

Вау. 

Похоже, то, что надо.  Да! Двойная перегрузка. И "квадратную скобку", и "присваивание" перегружаем. Хочется как раз для массива. 


Так и сделаю. 

Благодарю. Сам до подобного недотумкал. 

 
Alexey Viktorov #:

А конструктор с параметрами не поможет?

Так в том-то и проблема, что хочется по "квадратной скобке" добраться до элемента существующего (а не создаваемого) массива.

Собственно, я сейчас пишу свой переносимый класс вектора и матрицы, чтобы можно было использовать один и тот же код в MT4 и MT5, причём, чтобы в МТ5 использовались "нативные" типы vector и matrix, а в MT4 - в этот код "подставлялись" бы мои самописные CDblVector и СDblMatrix.  Вот, в коде надо предусмотреть возможность устанавливать элементы векторов оператором квадратной скобки.

 

Хм... Оказывается, все хитрее. 

Предложенная двойная перегрузка нормально работает, когда нам надо присвоить с помощью "квадратной скобки" элемент массива:

a[i] = i  // Двойная перегрузка хорошо работает.

Однако, при этом мы не можем получить элемент массива, чтобы присвоить его:

double dNullEnement = a[0];  // Так уже не выйдет, двойная перегрузка мешает.

Перегруженный оператор возвращает не double, а указатель на класс, и компилятор не может его преобразовать в double.

Сейчас пытаюсь придумать варианты с дополнительным классом-хелпером, чтобы, все-таки получилось с помощью оператора "квадратные скобки" и присваивать элементы массива, и получать их. 

 
class A
{
private:
  uint Pos;

public:
  double Array[5];
  
  A* operator []( const uint iPos )
  {
    this.Pos = iPos;
    
    return(&this);
  }  

  double operator []( const int iPos ) const
  {
    return(this.Array[iPos]);
  }  
  
  void operator =( const double Value )
  {
    this.Array[this.Pos] = Value;
  }
};

void OnStart()
{
  A a;
  
  for (uint i = 0; i < 5; i++)
    a[i] = i;
    
  for (int i = 0; i < 5; i++)
    Print(a[i]);
}
 

Сейчас ещё раз проверю... 

Аааа... Хытрэц... С помощью "const" выкрутился. 

Браво,  fxsaber ! 

Ты крут, а я перед тобой сынок. Премного благодарен.