Ошибки, баги, вопросы - страница 2656

Andrey Dik:

В справке про EventChartCustom () сказано:

sparam

[in]  Параметр события типа string, передаваемый функции OnChartEvent. Если строка имеет длину больше, чем 63 символа, то строка усекается.

Однако успешно передается строка длиной 96 символов, что то изменилось?

128 байтов. Это 127 uchar-символов, или 63 ushort-символов.

Как в MQL реализовать такую вещь:

#include <Controls\Button.mqh>

  class Collection
  {
    protected:
      int size;

    public:
      Collection(CWnd &refs[]) { size = ArraySize(refs); }
  };


void OnStart()
{
  CButton buttons[];
  CWnd wnd[];
  Collection data1(wnd);     // ok
  Collection data2(buttons); // error
  // 'buttons' - parameter conversion not allowed
  // 'buttons' - variable of the same type expected
}
?
fxsaber :

128 байтов. Это 127 uchar-символов, или 63 ushort-символов.

Это на самом деле 160 байтов.


Файлы:
Stanislav Korotky:

Как в MQL реализовать такую вещь:

?
Унаследовать CButtons от CWnd
Или это объекты классов станд.библиотеки?
Если каждый из них унаследован от CObject, то: 
Collection(CObject &refs[]) { size = ArraySize(refs); }

Уважаемые разработчики, можно ли поменять как то UTM метки ?


Или Можете ли Вы привести метки в порядок ?

utm_campaign=mt4terminal

utm_source=properties.indicator

utm_medium=indicatorName

utm_term=indicatorVersion

utm_content=Year


Сейчас текущие UTM  метки не информативны...

Finteza panel: website analytics and advertising management
Finteza panel: website analytics and advertising management
  • panel.finteza.com
Real-time unsampled analytical data, traffic attribution and quality evaluation, creation of conversion funnels and targeted advertising in apps and websites
Artyom Trishkin:
Унаследовать CButtons от CWnd
Или это объекты классов станд.библиотеки?
Если каждый из них унаследован от CObject, то: 

В том то и дело что дерево классов имеет общий узел CWnd (CObject дальше, вообще в корне).

CButton -> CWndObj -> CWnd -> CObject.

Если изменить параметр в методе на CObject, получаем в 2 раза больше ошибок:

'wnd' - parameter conversion not allowed
'wnd' - variable of the same type expected
'buttons' - parameter conversion not allowed
'buttons' - variable of the same type expected

Аналогичная иерархия классов работает для случая не массива. Вот компилируемый код:

#include <Controls\Button.mqh>

  class Collection
  {
    protected:
      int size;

    public:
      Collection(CWnd &object) { size = 1; }
  };


void OnStart()
{
  CButton button1;
  CWnd wnd1;
  Collection data1(wnd1);     // ok
  Collection data2(button1);  // ok
}

Вопрос, как сделать, чтобы и для массива работало?

Я знаю шаблон помогает, но его как раз хочется избежать.

ИМХО, должно без шаблонов работать по праву наследования.

Проверил как в C++.

class CWnd
{
  public:
    int x;
    CWnd(int _x = 0): x(_x){}
};
class CButton: public CWnd
{
  public:
    CButton(): CWnd(10) {}
};

class Collection
{
  public:
    Collection(CWnd (&ptrs)[1]) { cout << ptrs[0].x; }
};


int main()
{
  CButton buttons[1];
  CWnd wnd[1];
  Collection data1(wnd);
  Collection data2((CWnd (&)[1])buttons);
  return 0;
}

Работает. Но MQL такое не переваривает, что с индексом, что без.

Stanislav Korotky:

В том то и дело что дерево классов имеет общий узел CWnd (CObject дальше, вообще в корне).

CButton -> CWndObj -> CWnd -> CObject.

Если изменить параметр в методе на CObject, получаем в 2 раза больше ошибок:

Аналогичная иерархия классов работает для случая не массива. Вот компилируемый код:

Вопрос, как сделать, чтобы и для массива работало?

Я знаю шаблон помогает, но его как раз хочется избежать.

ИМХО, должно без шаблонов работать по праву наследования.

Проверил как в C++.

Работает. Но MQL такое не переваривает, что с индексом, что без.

Для C++ вот так наглядней Ваш пример будет. Запустите и посмотрите, что получится)))

class CWnd
{
public:
    int x;
    CWnd(int _x = 10) : x(_x) {}
};
class CButton : public CWnd
{
    int a;
public:
    CButton(int _a=6) : CWnd(),a(_a) {}
};

class Collection
{
public:
    Collection(CWnd* ptr,size_t size) {
        for (int i = 0; i < size; cout << ptr[i++].x<<endl);
    }
};

int main()
{
    CButton buttons[10];
    CWnd wnd[10];
    Collection data1(&wnd[0],_countof(wnd));
    cout << "------------------------------" << endl;
    Collection data2(&buttons[0],_countof(buttons));
    return 0;
}

Мда, мой косяк. Но тогда возникает следующий вопрос. Вот этот код C++ работает (уже точно как надо ;-)).

class Base
{
  public:
    virtual void method1(void) { cout << "2\n"; }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { cout << "3\n"; }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr->T::method1();
    }
};

int main()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // ok

  return 0;
}

Аналогичный MQL дает ошибку:

class Base
{
  public:
    virtual void method1(void) { Print(__FUNCSIG__); }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { Print(__FUNCSIG__); }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr.T::method1(); // <<< 'Base' is not a class, struct or union
    }
};


void OnStart()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // causes the error above
Stanislav Korotky:

Мда, мой косяк. Но тогда возникает следующий вопрос. Вот этот код C++ работает (уже точно как надо ;-)).

Аналогичный MQL дает ошибку:

не знаю задачу, но по моему Вы ищете что то такое:

typedef void(*PTR)(void);

в MQL это указатель на функцию  void func(void)

 в классе можно объявить поле с типом PTR и затем присвоить ему функцию и затем "разыменовывать указатель" и вызвать функцию 

с передачей функций написанных в процедурном стиле в класс работает без проблем, методы класса, скорее всего, так просто не получится передавать, можно через dynamic_cast  попробовать, но код очень запутанный получится

Igor Makanu:

не знаю задачу, но по моему Вы ищете что то такое:

в MQL это указатель на функцию  void func(void)

 в классе можно объявить поле с типом PTR и затем присвоить ему функцию и затем "разыменовывать указатель" и вызвать функцию 

с передачей функций написанных в процедурном стиле в класс работает без проблем, методы класса, скорее всего, так просто не получится передавать, можно через dynamic_cast  попробовать, но код очень запутанный получится

typedef не прокатит с методом.

dynamic_cast работает в сторону наследника (более длинной цепочки), то есть если в указателе на base содержится derived, то можно привести к derived и, если он не NULL (т.е. каст нормальный),  вызвать его метод. Но когда ситуация наоборот, как в моем случае, есть указатель на derived то он по определению является и base. И любой вызов его виртуального метода просекает, что в указателе "сидит" derived и вызывает переопределенную реализацию. А нужно базовую.

Для этого есть вышеуказанная синтаксическая конструкция в C++, но MQL - не C++. По-видимому, пока никак.

Я сделал у себя обходной трюк, но он не во всех задачах может прокатить.

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