MQL5 Компилятор не различает класс и указатель на него - страница 12

 
Georgiy Merts:

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

Я говорю про объекты, созданные по new:

В стандарте С# указывается: "И объекты типа значения, такие как структуры, и объекты ссылочного типа, такие как классы, уничтожаются автоматически, но объекты типа значения уничтожаются при уничтожении содержащего их контекста, в то время как объекты ссылочного типа уничтожаются сборщиком мусора через неопределенное время после удаления последней ссылки на них"

Вот, мне это "неопределенное время" - не нравится. Хотя, я даже допускаю, что сборщик мусора может удалить объект куда эффективнее, чем я сам, удаляя объект в деструкторе создавшего его класса.

Логично, раз никто не ссылается, значит, обект уже никому не нужен, при следущей сборке мусора он будет удален. Время да, непредсказуемо, хотя пожно попросить GC сделать сборку немедленно. Но это тоже просьба, а не приказ ))

 
Georgiy Merts:

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

В шарпах предусмотрена функция для защиты объекта от удаления сборщиком мусора.

https://docs.microsoft.com/ru-ru/dotnet/api/system.runtime.interopservices.gchandle.alloc?view=netcore-2.0

// for standalone object
public byte[] RawSerialize(object objAny)
{
int rawsize = Marshal.SizeOf(objAny);
byte[] m_obj = new byte[rawsize];

        GCHandle hObj = GCHandle.Alloc(m_obj, GCHandleType.Pinned);

        Marshal.StructureToPtr(objAny, hObj.AddrOfPinnedObject(), false);
        hObj.Free();

return (m_obj);
}
GCHandle.Alloc Method (System.Runtime.InteropServices)
GCHandle.Alloc Method (System.Runtime.InteropServices)
  • dotnet-bot
  • docs.microsoft.com
Выделяет дескриптор для указанного объекта.Allocates a handle for the specified object.
 
Alexey Navoykov:

А теперь начинаете отчаянно придумывать оправдания, почему вы о ней не знали ;) 

Какая разница, когда её ввели: сразу или спустя месяца?  Вы о ней как не знали, так и продолжали бы не знать, если б я не сказал )  

Боюсь сгореть от стыда, но я и о & не знал до недавнего времени, пока у fxsaber где-то не увидел. А иначе так бы и пользовался GetPointer

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

 
SemenTalonov:

Наверное всё таки пойдут в направлении C# где в "managed code" указателей нет а всё есть объект, даже простые типы bool int double и т.д.

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

SemenTalonov:

ВОт как раз по ИМХО это необходимо, чтобы не забывать с чем именно имеешь дело (объект или указатель на него).

Чтобы не забывать нужно точно решить в начале, в каких ситуациях ты используешь объекты, а в каких указатели (в идеальном случае - никогда объекты и всегда указатели)

А писать каждый раз лишние буквы для этого (особенно париться со скобками) - откровенно глупо

К тому же в этом случае описанном Вами операция присваивания используется не по отношению к объекту, а по отношению к его не объектному полю, что в принципе исключает вероятность ошибки (не имеет значения тип указателя в такой операции)

 
Ilya Malev:

Чтобы не забывать нужно точно решить в начале, в каких ситуациях ты используешь объекты, а в каких указатели (в идеальном случае - никогда объекты и всегда указатели)

Даже не "чужой" а свой код открываешь через продолжительное время (год, два) и ругаешь себя, что не оставлял комменты в "тонких" местах а если ещё и объекты от указателей будут не отличимы этож вообще ахтунг. С отказом от автообъектов также не согласен. Их применение делает код заметно компактнее и снимает заботу о судьбе объекта после того как он стал не нужен. Кроме того, уверен, поскольку время жизни такого объекта компилятору известно заранее, то он может дать более оптимизированный код чем в случае с динамическим созданием.

Ilya Malev:

А писать каждый раз лишние буквы для этого (особенно париться со скобками) - откровенно глупо

К тому же в этом случае описанном Вами операция присваивания используется не по отношению к объекту, а по отношению к его не объектному полю, что в принципе исключает вероятность ошибки (не имеет значения тип указателя в такой операции)

 Глупость сия происходит от того, что в MQL, обозначить, иным способом, доступ к объекту по указателю никакой возможности нет. В C/C++ конечно было бы лаконичней

pA->iValue

Причина отсутствия стрелки, наверное такая же как и с '*' изначально (неизвестна). У меня в Qt (да и в VS наверное тоже) редактор автоматом заменяет '.' на '->' если доступ к объекту происходит по указателю, т.е. лишних телодвижений вообще 0. Я не сомневаюсь что MQ могут добавить такой функционал в редактор, при желании. А так, получается, в приведенном примере, единственный признак того что имеешь дело с указателем, это префикс 'p' в имени. И только по тому что я не забыл. Если все так "тактичны" то всё в порядке))

Т.е. потенциально опасные места кода должны быть явно обозначены. О них не надо помнить их надо видеть. Необходимость подобного "оформления отношений" с объектами была бы очевидней на более сложных примерах чем приведенный выше. Например, когда член класса сам является указателем на что либо.

Предоставив единообразный подход работы с POINTER_AUTOMATIC и POINTER_DYNAMIC, нам дают обманчивое представление о подобии этих типов указателей. Но на самом деле, это разные сущности и требуют разного отношения. Это и есть основная тема ветки. Ну самое очевидное конечно: если POINTER_AUTOMATIC всегда указывает на реально существующий объект, то POINTER_DYNAMIC может быть и пустым

А я просто напомню всевозможные вариации доступа к данным (пусть и C/C++, пока наши пути совпадают)

ОператорСинтаксисПерегружаемыйРеализован в СиПример
Член типа TОпределение вне класса
Обращение к элементу массиваa[b]ДаДаR T::operator [](S b);
н/д
Непрямое обращение («объект, на который указывает a»)*aДаДаR T::operator *();R operator *(T a);
Ссылка («адрес a»)&aДаДаR T::operator &();R operator &(T a);
Обращение к члену структуры («член b объекта, на который указывает a»)a->bДаДаR* T::operator ->();[note 5]
н/д
Обращение к члену структуры («член b объекта a»)a.bНетДан/д
Член, на который указывает b в объекте, на который указывает a[note 6]a->*bДаНетR T::operator ->*(S b);R operator ->*(T a, S b);
Член, на который указывает b в объекте aa.*bНетНетн/д
 
SemenTalonov:

Ну самое очевидное конечно: если POINTER_AUTOMATIC всегда указывает на реально существующий объект, то POINTER_DYNAMIC может быть и пустым

Если "самое очевидное" уже является ложным, стоит ли всерьез рассматривать и отвечать на все остальное?

POINTER_AUTOMATIC это не тип переменной, это её статус. В следующий момент её статус может быть совсем другим. Включая POINTER_INVALID, разумеется
 
Ilya Malev:

Если "самое очевидное" уже является ложным, стоит ли всерьез рассматривать и отвечать на все остальное?

Я бы хотел пояснений на этот счет если возможно

 
Ilya Malev:
POINTER_AUTOMATIC это не тип переменный, это её статус. В следующий момент её статус может быть совсем другим

Конечно не тип. Т.е. автообъект стать указателем со статусом POINTER_DYNAMIC, например? Разумеется имелся ввиду статус POINTER_INVALID при объявлении указателя например.

 
SemenTalonov:

Я бы хотел пояснений на этот счет если возможно

Просто в МКЛ все видимо не так, как в С++. Тут указатель не является отдельным типом данных ни разу по сути, а поэтому и то и другое является объектом, а в переменной лежит его хендл. При этом у переменной есть скрытое свойство константности (если объявлено без *), но это не делает её по сути переменной другого типа, только запрещает присваивать ей другой хендл. 

 

То есть объявите

   A* const b=new A;

И будет Вам точно такой же "автообъект", только удалять его Вы будете сами

Причина обращения: