MQL5 The compiler does not distinguish between a class and a pointer to it - page 12

 
Georgiy Merts:

No. Clearly, in this case, the variable must be deleted on exit from the block.

I am talking about objects created by new:

The C# standard specifies:"Both value-type objects, such as structures, and reference-type objects, such as classes, are destroyed automatically, but value-type objects are destroyed when the context containing them is destroyed, while reference-type objects are destroyed by the rubbish collector indefinitely after the last reference to them is removed."

Here, I don't like this "unpredictable time". Although, I even admit that rubbish collector can delete the object much more effectively, than I myself delete the object in the destructor of the class which created it.

Logically, since no one is referencing it means no one needs the object anymore, it will be deleted at the next rubbish collection. Time is unpredictable, although you can ask GC to build it immediately. But this is also a request, not an order ))).

 
Georgiy Merts:

I'm not saying that the rubbish collector will delete a live object or a pointer. I'm saying it will remove it when it wants to.

Sharpe has a function to protect the object from being deleted by the rubbish collector.

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:

And now you're desperately trying to make up excuses why you didn't know about it ;)

What difference does it make if they introduced it immediately or months later? You wouldn't have known about it if I hadn't told you.)

I`m afraid to burn with shame, but I didn`t know about & & until recently, until I saw it on fxsaber somewhere. I would use GetPointer otherwise.

But I've paid attention to absence of possibility to overload some operations with objects in September somewhere and at that time I've tried to solve this problem by myself and some people wrote to me that such possibility doesn't exist. And now it turns out that it exists, so I wonder when exactly it appeared (and why it's not in the help).

 
SemenTalonov:

Probably, they will go in the direction of C# where "managed code" has no pointers and everything has an object, even simple types bool int double, etc.

That would be nice, but it is unlikely that they will change anything in this direction, because it is a complete change in the concept of the terminal language, and such things are rarely done.

SemenTalonov:

Exactly according to IMHO it's necessary not to forget what exactly you deal with (object or pointer to it).

In order not to forget, you must decide for sure at the beginning when you use objects and when you use pointers (ideally never objects and always pointers).

And it's silly to write each time extra letters for it (especially to bother with parentheses).

Besides, in this case, the assignment operation described by you is used not in relation to an object but to its non-object field what, in principle, excludes a probability of an error (the pointer type in such operation does not matter).

 
Ilya Malev:

In order not to forget, you must decide exactly at the beginning when you use objects and when you use pointers (ideally - never objects and always pointers).

When you open your own code after a while (a year or two) and scold yourself that you didn't leave comments in the "delicate" places, or if you can't distinguish objects from pointers, it's like a total loss. I also don't agree that we should refuse using autoobjects. Using them makes the code compact and reduces one's concern about the object's fate after it's become obsolete. Besides, I'm sure the lifetime of such an object is known to the compiler beforehand and therefore the compiler can provide a more optimized code than in case of dynamic creation.

Ilya Malev:

And it's just silly to write additional letters each time for that (especially to bother with parentheses).

Besides, in the case you describe, the assignment operation is used not relative to an object but to its non-object field what basically excludes a probability of error (the pointer type in such operation does not matter).

This nonsense comes from the fact that in MQL, there is no other way to denote access to an object by a pointer. In C/C++, of course, it would be more laconic.

pA->iValue

The reason for the absence of the arrow is probably the same as with the'*' originally (unknown). In Qt (and probably VS too), the editor automatically replaces '.' with '->' if the object is accessed through a pointer, i.e. no extra work at all. I have no doubt that MQ can add such functionality to the editor, if desired. As it turns out, in this example the only sign of dealing with a pointer is the 'p' prefix in the name. And that's only because I haven't forgotten. If everyone is so 'tactful' then that's fine))

I.e. potentially dangerous code fragments should be explicitly marked. You don't have to remember them, you have to see them. The necessity of such "formalization of relations" with objects would be clearer on more complicated samples than given above. For instance, when a class member itself is a pointer to something.

By providing a uniform way of dealing withPOINTER_AUTOMATIC andPOINTER_DYNAMIC, we are given the misleading idea that these types of pointers are similar. But in fact they are different entities and require different treatment.This is the main subject of this branch.The most obvious one is of course: whilePOINTER_AUTOMATIC always points to a real object,POINTER_DYNAMIC can be empty too.

And I'll just remind you of all the different variations of data access (albeit C/C++, as long as our paths match)

OperatorSyntaxReloadableImplemented inCExample
Member of type TDefinition outside the class
Accessing an array elementa[b]YesYesRT::operator[](Sb);
n/a
Indirect reference ("object pointed toby a")*aYesYesRT::operator*();R operator*(Ta);
Reference ("addressa")& aYesYesR operatorT::operator&();R operator&(Ta);
Referencing a member of the structure ("the b member of the object pointed to bya")a-> bYesYesR*T::operator->();[note 5]
N/A
Reference to a member of a structure ("b member of objecta")a. bNoYesn/a
Member pointed to by b in an object pointed to bya[note 6]a->*bYesNoR operatorT::operator->*(Sb);R operator->*(Ta, Sb);
The member pointed to by b in the objectaa.*bNoNoN/A
 
SemenTalonov:

Well the most obvious of course: ifPOINTER_AUTOMATIC always points to a real object,POINTER_DYNAMIC can be empty too.

If the "most obvious" is already false, is it worth seriously considering and answering everything else?

POINTER_AUTOMATIC is not the type of variable, it is its status. The next moment its status may be quite different. Including POINTER_INVALID, of course.
 
Ilya Malev:

If the "most obvious" is already false, is it worth seriously considering and responding to everything else?

I would like clarification on this if possible

 
Ilya Malev:
POINTER_AUTOMATIC is not a type of a variable but its status. At the next moment, its status may be quite different

Certainly not a type. You mean that the auto-object becomes a pointer with the statusPOINTER_DYNAMIC, for instance? What is meant here is thePOINTER_INVALIDstatus, for example, when declaring a pointer.

 
SemenTalonov:

I would like some clarification on this, if possible.

It's just that in MCL it's apparently not the same as in C++. Here a pointer is not a separate data type at all, so both are objects and a variable contains its handle. A variable has a hidden constant property (if declared without *), but that doesn't essentially make it a variable of a different type, only prohibits assigning a different handle to it.

 

That is, declare

   A* const b=new A;

And you will have exactly the same "auto-object", only you will delete it yourself

Reason: