Тогда в общем случае, проблема звучит как: компилятор позволяет, в указатель типа POINTER_AUTOMATICсохранить указатель типа POINTER_DYNAMIC, и наоборот.
Да не совсем бинго. Для простых объектов работает присваивание оператором =. Не баг точно.
Тогда в общем случае, проблема звучит как: компилятор позволяет, в указатель типа POINTER_AUTOMATICсохранить указатель типа POINTER_DYNAMIC, и наоборот.
Нет. Когда в автоматик из динамик - это не указатель присваивается, а выполняется копирование объекта - значений его полей, но только с простыми объектами.
Да не совсем бинго. Для простых объектов работает присваивание оператором =. Не баг точно.
Вот-вот, это самый главный момент.
Лично я считаю, что нельзя использовать оператор присваивания для объектов, если этот оператор не определен явно, даже если объекты простые. Еще как-то можно согласиться на присваивание простых структур. Но классы, в которых обязательно вызывается конструктор (как минимум, неявно) - присваиваться могут только явно определенными операторами.
На мой взгляд, это было сделано для упрощения жизни новичкам.
Лично я считаю, что нельзя использовать оператор присваивания для объектов, если этот оператор не определен явно, даже если объекты простые. Еще как-то можно согласиться на присваивание простых структур. Но классы, в которых обязательно вызывается конструктор (как минимум, неявно) - присваиваться могут только явно определенными операторами.
На мой взгляд, это было сделано для упрощения жизни новичкам.
И сложные удобны - без этого нельзя вернуть MqlTradeRequest, например. И в структурах также обязательно вызывается конструктор.
Есть версия что MQL это такой очень обрезанный C#. Исходя из этого, становится понятно поведение MQL компилятора в данном случае. Ведь в C# классы всегда размещаются в куче, следовательно:
//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+class A
{
public:
int iValue;
};
//......................
A m_A[2];
voidOnStart()
{
// Разместили A в куче, указатель на A передали в m_A[1]
m_A[1] = new A();
// Разместили A на стеке...
A a;
// А вот фиг вам! ля-ля-ля;) Там вам не тут. 'a' - класс и размещается в куче. Указатель на него передается внутреннему сборщику мусора// А раз так, то теперь он AUTOMATIC и к нему нельзя применить delete, т.к. внутренний сборщик мусора его удалит сам // скопировали указатель a в массив
m_A[0] = a;
}
//+------------------------------------------------------------------+
Теперь разберемся с массивом m_A. Раз m_A массив классов, а классы размещаются всегда в куче, следовательно нет необходимости указывать является ли массив m_A массивом указателей или массивом самих объектов, т.к. для классов всегда работает только первый вариант. Раз m_A всегда массив указателей, то в MQL сделана поблажка: в нем можно не указывать хранит ли он ссылочные типы или значимые. Следовательно A* m_A[2] == A m_A[2]. Аминь.
Есть версия что MQL это такой очень обрезанный C#. Исходя из этого, становится понятно поведение MQL компилятора в данном случае. Ведь в C# классы всегда размещаются в куче, следовательно:
Теперь разберемся с массивом m_A. Раз m_A массив классов, а классы размещаются всегда в куче, следовательно нет необходимости указывать является ли массив m_A массивом указателей или массивом самих объектов, т.к. для классов всегда работает только первый вариант. Раз m_A всегда массив указателей, то в MQL сделана поблажка: в нем можно не указывать хранит ли он ссылочные типы или значимые. Следовательно A* m_A[2] == A m_A[2]. Аминь.
Неверный вывод. m_A - массив объектов, а не указателей. И эти объекты полностью уничтожаются. Не уничтожается new A.
class A
{
public:
int iValue;
~A()
{
Print(__FUNCSIG__);
}
};
//......................
A m_A[2];
voidOnStart()
{
A a;
A* b = new A;
m_A[0] =a; // копирование объекта, а не указателя
m_A[1] = b; // копирование объекта, а не указателя// по выходу уничтожится три объектаdelete b; // а так - четыре.
}
A m_A[2];
voidOnStart()
{
A a;
A* b = new A();
printf("SizeOf 'a' object: %i SizeOf pointer 'b' to object: %i", sizeof(a), sizeof(b));
a =b;
b =a;
m_A[0] = a;
m_A[1] = b;
}
SizeOf 'a' object: 20 SizeOf pointer to 'b' object: 8
Бинго!
Да не совсем бинго. Для простых объектов работает присваивание оператором =. Не баг точно.
...
Нет. Когда в автоматик из динамик - это не указатель присваивается, а выполняется копирование объекта - значений его полей, но только с простыми объектами.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
MQL5 Компилятор не различает класс и указатель на него
SemenTalonov, 2019.01.10 04:18
С каких времен определены (вопрос разработчикам)
и как они работают? Следующий компилируемый код выглядит бредово
И здесь ситуация не ясна
Да не совсем бинго. Для простых объектов работает присваивание оператором =. Не баг точно.
Вот-вот, это самый главный момент.
Лично я считаю, что нельзя использовать оператор присваивания для объектов, если этот оператор не определен явно, даже если объекты простые. Еще как-то можно согласиться на присваивание простых структур. Но классы, в которых обязательно вызывается конструктор (как минимум, неявно) - присваиваться могут только явно определенными операторами.
На мой взгляд, это было сделано для упрощения жизни новичкам.
Вот-вот, это самый главный момент.
Лично я считаю, что нельзя использовать оператор присваивания для объектов, если этот оператор не определен явно, даже если объекты простые. Еще как-то можно согласиться на присваивание простых структур. Но классы, в которых обязательно вызывается конструктор (как минимум, неявно) - присваиваться могут только явно определенными операторами.
На мой взгляд, это было сделано для упрощения жизни новичкам.
И сложные удобны - без этого нельзя вернуть MqlTradeRequest, например. И в структурах также обязательно вызывается конструктор.
Есть версия что MQL это такой очень обрезанный C#. Исходя из этого, становится понятно поведение MQL компилятора в данном случае. Ведь в C# классы всегда размещаются в куче, следовательно:
Теперь разберемся с массивом m_A. Раз m_A массив классов, а классы размещаются всегда в куче, следовательно нет необходимости указывать является ли массив m_A массивом указателей или массивом самих объектов, т.к. для классов всегда работает только первый вариант. Раз m_A всегда массив указателей, то в MQL сделана поблажка: в нем можно не указывать хранит ли он ссылочные типы или значимые. Следовательно A* m_A[2] == A m_A[2]. Аминь.
Есть версия что MQL это такой очень обрезанный C#. Исходя из этого, становится понятно поведение MQL компилятора в данном случае. Ведь в C# классы всегда размещаются в куче, следовательно:
Теперь разберемся с массивом m_A. Раз m_A массив классов, а классы размещаются всегда в куче, следовательно нет необходимости указывать является ли массив m_A массивом указателей или массивом самих объектов, т.к. для классов всегда работает только первый вариант. Раз m_A всегда массив указателей, то в MQL сделана поблажка: в нем можно не указывать хранит ли он ссылочные типы или значимые. Следовательно A* m_A[2] == A m_A[2]. Аминь.
Неверный вывод. m_A - массив объектов, а не указателей. И эти объекты полностью уничтожаются. Не уничтожается new A.
Неверный вывод. m_A - массив объектов, а не указателей. И эти объекты полностью уничтожаются. Не уничтожается new A.
Хороший пример. Хм. Тогда будем думать дальше.
пхах)) я вообще в шоке с этого
пхах)) я вообще в шоке с этого
А что не так? В одном случае объект, в другом случае указатель.