MQL5 编译器不区分类和它的指针 - 页 12

 
Georgiy Merts:

不,很明显,在这种情况下,该变量必须在退出区块时被删除。

我说的是由新创建的对象。

C#标准中规定。"价值型对象(如结构)和引用型对象(如类)都会被自动销毁,但价值型对象会在包含它们的上下文被销毁时被销毁,而引用型对象会在对它们的最后一个引用被移除后被垃圾收集器无限期地销毁"

在这里,我不喜欢这种 "不可预知的时间"。虽然,我甚至承认,垃圾收集器可以更有效地删除对象,而不是我自己在创建对象的类的析构器中删除对象。

从逻辑上讲,既然没有人引用它就意味着没有人再需要这个对象,它将在下一次垃圾收集时被删除。时间是不可预测的,尽管你可以要求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

但我注意到,在9月份的时候,没有可能用对象重载一些操作,当时我试图自己解决这个问题,有些人给我写信说这种可能性不存在。而现在事实证明它是存在的,所以我想知道它究竟是什么时候出现的(以及为什么它没有出现在帮助中)。

 
SemenTalonov:

也许,他们会朝着C#的方向发展,在那里,"托管代码 "没有指针,所有的东西都有一个对象,甚至简单的类型bool int double等等。

这很好,但他们不太可能在这个方向上改变什么,因为这是对终端语言概念的彻底改变,而这样的事情很少有人做。

谢门-塔洛诺夫

确切地说,根据IMHO,有必要不要忘记你到底在处理什么(对象或指针)。

为了不忘记,你必须在一开始就确定什么时候使用对象,什么时候使用指针(最好不要使用对象,总是使用指针)。

而且每次都为它写额外的字母是很愚蠢的(特别是要用括号)。

此外,在这种情况下,你所描述的赋值操作不是用于对象,而是用于其非对象字段,原则上排除了错误的可能性(这种操作中的指针类型并不重要)。

 
Ilya Malev:

为了不忘记,你必须在一开始就准确地决定什么时候使用对象,什么时候使用指针(最好是--永远不要使用对象,永远使用指针)。

当你在很久之后(一两年)打开自己的代码,责备自己没有在 "微妙 "的地方留下注释,或者你不能区分对象和指针,这就像一个完全的损失。我也不同意放弃自动对象的做法。使用它们可以使代码紧凑,并减少人们对对象过时后的命运的担忧。此外,我确信编译器事先知道这样一个对象的寿命,因此,编译器可以提供比动态创建更优化的代码。

Ilya Malev:

而且每次都要写额外的字母是很愚蠢的(特别是要用括号)。

此外,在你描述的情况下,赋值操作不是相对于对象使用的,而是相对于其非对象字段使用的,这基本上排除了出错的可能性(这种操作中的指针类型并不重要)。

这种无稽之谈来自于这样一个事实:在MQL中,没有其他方式可以通过指针来表示对一个对象的访问。当然,在C/C++中,它将更加简洁明了。

pA->iValue

没有箭头的原因可能与最初的'*'相同(未知)。在Qt(可能也包括VS)中,如果对象是通过指针访问的,编辑器会自动将'.'替换为'->',也就是说,完全没有额外的工作。我毫不怀疑,如果需要的话,MQ可以在编辑器中加入这样的功能。事实证明,在这个例子中,处理指针的唯一标志是名称中的'p'前缀。而这只是因为我没有忘记。如果每个人都这么 "圆滑",那就好了))。

也就是说,有潜在危险的代码片段应该被明确标记。你不需要记住它们,你必须看到 它们。在比上面给出的更复杂的样本上,这种与对象的 "关系形式化 "的必要性会更清楚。例如,当一个类成员本身是一个指向某物的指针时。

通过提供一个处理POINTER_AUTOMATIC和POINTER_DYNAMIC 的统一方法,我们被误导了,认为这些类型的指针是相似的但事实上它们是不同的实体,需要不同的处理方式。这是本分支的主要议题。 当然,最明显的是:虽然POINTER_AUTOMATIC总是指向一个真实的对象,但POINTER_DYNAMIC也可以是空的

我就提醒你所有数据访问的不同变化(尽管是C/C++,只要我们的路径匹配)。

运营商语法可重新装填C语言 实现例子
T类型的成员类外的定义
访问一个数组元素a[b]RT::operator[](Sb)。
不适用
间接引用("由a指向 的对象")。*aRT::operator*()。R运算符*(Ta)。
参考("地址a")。& aR 运算符T::运算符&()。R运算符&Ta
引用结构中的一个成员("a指向 的对象的b成员")。a-> bR*T::operator->();[注5]
不适用
对一个结构的成员的引用(" 对象ab成员")。a. b没有不适用
b指向 的成员在a指向 的对象中[注6]a->*b没有R 运算符T::运算符->*Sb)。R运算符->*TaSb
对象a由b指向 的成员a.*b没有没有不适用
 
SemenTalonov:

那么最明显的当然是:如果POINTER_AUTOMATIC总是指向一个真实的对象,那么POINTER_DYNAMIC也可以是空的

如果 "最明显的 "已经是假的,那么是否值得认真考虑和回答其他的事情?

POINTER_AUTOMATIC 不是变量的类型,而是其状态。下一刻,它的地位可能就完全不同了。当然,包括POINTER_INVALID。
 
Ilya Malev:

如果 "最明显的 "已经是假的,那么是否值得认真考虑和回应其他一切?

如果可能的话,我希望对此进行澄清

 
Ilya Malev:
POINTER_AUTOMATIC 不是一个变量的类型,而是它的状态。在下一个时刻,它的状态可能完全不同

当然不是一个类型。你的意思是自动对象变成一个状态为POINTER_DYNAMIC的指针,比如说? 所谓的POINTER_INVALID状态 是指在声明一个指针的时候,比如说

 
SemenTalonov:

如果可能的话,我希望对此进行一些澄清。

只是,在MCL中,它显然与C++中的不一样。在这里,指针根本就不是一个独立的数据类型,所以两者都是对象,而一个变量包含了它的句柄。一个变量有一个隐藏的常量属性(如果声明时没有*),但这本质上并没有使它成为一个不同类型的变量,只是禁止给它分配一个不同的句柄。

 

就是说,宣布

   A* const b=new A;

而你将拥有完全相同的 "自动对象",只是你将自己删除它。