Нужно вернуть из класса массив или иметь возможность менять массив внутри класса(массив нужен вне класса, то есть на глобальном уровне) - страница 2

 
Ну, покажите на примере как сделать) Я по разному пробовал, пока не получается.
 
forexman77 #:
Ну, покажите на примере как сделать) Я по разному пробовал, пока не получается.

да, так как я думал, у меня тоже не получаеся.

 
forexman77 #:

Да. Класс может вернуть, только одно значение, а мне нужно много. Как в Питоне не получится же сделать вернуть return  с массивом?

Можно вернуть структуру (в ней много даных). 

Можно создать экземпляр класса по new, и вернуть указатель на него (а внутри экземпляра - много данных). 

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

Можно иметь  глобальный экземпляр объекта, доступный отовсюду, и внутри функции менять его даные.

 
forexman77:

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

У меня не меняется. Что делаю не так?

вызываю в скрипте:


Можно массив обернуть в класс и объект класса передавать по ссылке.

Можно шаблонный класс сделать:

//+------------------------------------------------------------------+
template <typename T>
class TArray {
public:
   TArray() {};
   TArray(int size) {
      ArrayResize(array,size);
   };
   ~TArray(void) {};
   //---
   int Resize(int new_size, int reserve_size=0);
   T array[];
};
//---
template <typename T>
int TArray::Resize(int new_size, int reserve_size=0) {
   return  ArrayResize( array, new_size, reserve_size);
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
class test {
private:
   TArray<double> *m_array;
   int mperiod;
   int me;
   double mPr;
   string mSymbol_;

public:
   void parametr(TArray<double> &array,int aperiod_,int ae,double aPr, string aSymbol_) {
      mperiod=aperiod_;
      me=ae;
      mPr=aPr;
      mSymbol_=aSymbol_;

      //ArraySetAsSeries(m_array,true);
      //if(ArraySize(array)>0) {
      //   ArrayResize(m_array,ArraySize(array));
      //   ArrayCopy(m_array, array);
      //}
      m_array = &array;
   }


   double            abc() {
      m_array.array[0] = 3333333;
      m_array.array[1] = 1111111;
      Print("m_array.array[0]=", m_array.array[0], "m_array.array[1]=", m_array.array[1]);

      return(0);
   }

};
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
test zn;
TArray<double> otk;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
  otk.Resize(2);
  otk.array[0]=77777.0;
  otk.array[1]=10000.0;
//---
   zn.parametr(otk,1,2,4.0,"");
   zn.abc();
   Print("otk.array[0]=", otk.array[0], "otk.array[1]=", otk.array[1]);
   
   
  }
//+------------------------------------------------------------------+


PS.

Полноценно переопределить оператор [] не получится, т.к. в MQL нельзя вернуть ссылку на данные простого типа.

 
forexman77:

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

У меня не меняется. Что делаю не так?

вызываю в скрипте:

Самый простой и наглый способ - массив 

double            m_array[];

Перенесите из секции private в секцию public.

Если хотите отставить его в private, создайте методы для получения заданного элемента массива и для установки, еще парочка методов пригодится - изменение размера массива и получения размера массива.

Но наверно не это надо...

***

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

 
//+------------------------------------------------------------------+
class CTest
  {
public:
                     CTest(void)   {  }
                    ~CTest(void)   {  }
   void              abc(double  &m_array[])
     {
      m_array[0] = 3333.333;
      m_array[1] = 1111.111;

      return;
     }
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CTest zn;
   double   otk[2];
   otk[0]=77777.0;
   otk[1]=10000.0;
   Print("otk[0]=", otk[0], "otk[1]=", otk[1]);

   zn.abc(otk);
   Print("otk[0]=", otk[0], "otk[1]=", otk[1]);
}

И делов то.


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

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

Если очень хочется, то можно закостылить))))

Пример:

#define ARRAY __GetArr().arr

template<typename Type>
class ArrayWrape{
public:
   Type arr[];
};

struct A{
   int a;
   double b;
};

class Test{
   ArrayWrape<A> arr;
public:
   ArrayWrape<A>* __GetArr(){return &arr;};
};

void OnStart()
{
   int size=50;
   Test x;
   ArrayResize(x.ARRAY,size);
   for (int i=0;i<ArraySize(x.ARRAY);++i){
      x.ARRAY[i].a=i;
      x.ARRAY[i].b=MathSqrt(i);
   }
   for (int i=0;i<ArraySize(x.ARRAY);++i)
      PrintFormat("sqrt(%i)=%.5f",x.ARRAY[i].a,x.ARRAY[i].b);
}

PS/ Правда это не совсем то, что вам нужно.

PPS/ Развитие мысли:

#define ARRAY_PTR GetArray().arr
#define ARRAY(dType) ArrayWrape<dType>*
#define _A(dArr) dArr.arr

template<typename Type>
class ArrayWrape{
public:
   Type arr[];
};

struct A{
   int a;
   double b;
};

class Test{
   ArrayWrape<A> arr;
public:
   ArrayWrape<A>* GetArray(){return &arr;};
};

void OnStart()
{
   int size=50;
   Test x;
   ARRAY(A) arr=x.GetArray();
   ArrayResize(_A(arr),size);
   for (int i=0;i<ArraySize(x.ARRAY_PTR);++i){
      x.ARRAY_PTR[i].a=i;
      x.ARRAY_PTR[i].b=MathSqrt(i);
   }
   for (int i=0;i<ArraySize(x.ARRAY_PTR);++i)
      PrintFormat("sqrt(%i)=%.5f",_A(arr)[i].a,_A(arr)[i].b);
}
Причина обращения: