mql5语言的特点、微妙之处以及技巧 - 页 215

 

顺便说一下,如果你的对象是一个静态数组X x[n];而X有一个k-tor,那么它的所有元素字段将首先被清零,甚至是私有的,然后才会调用这个k-tor。因此,在将私有字段清零时,并没有违反OOP范式。

但事实上,构造函数不工作是一个错误。

 
mktr8591 #:

顺便说一下,如果你的对象是一个静态数组X x[n];而X有一个k-tor,那么它的所有元素字段将首先被清零,甚至是私有的,然后才会调用这个k-tor。因此,在将私有字段清零时,并没有违反OOP范式。

这很好。因此,事实证明,归零是在构造函数之前进行的,因此一切都很正确。谢谢你!

 
Igor Makanu #:

我看了看我在MQL5中的研究,情况可能更糟,我甚至在指标中抽出了几个TF的历史。

我可以在for语句中写很多东西 ))))

我从来没有遇到过for语句中的无效函数调用。我经常看到其他的变体。

 
mktr8591 #:
我忘了补充,如果一个类有非琐碎的字段(对象),那么在零初始化整个对象的这类字段后,它们的默认c-tor将被调用。

阅读。

值初始化的效果是。

1)如果T是一个没有默认构造函数 或有用户提供或删除的默认构造函数类类型,则对象被默认初始化
2如果 T是一个具有默认构造函数的类类型,该构造函数既不是用户提供的,也不是被删除的(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),则对象零初始 化,并且检查默认初始化的语义约束,如果 T有一个非实质性的默认构造函数,则对象默认初始化
3)如果T是一个数组类型,数组的每个元素都被初始化了
4) 否则,该对象零初始化


阅读关于default-initialized。

  • 如果 T是一个(可能是cv限定的非POD(直到C++11)的 类类型,那么构造函数将被考虑,并针对空参数列表进行重载解析。所选择的构造函数(是默认的构造函数 之一)被调用,以提供新对象的初始值
  • 如果 T是一个数组类型,数组的每个元素都被默认初始化。
  • 否则,不进行初始化:具有自动存储期限的对象(及其子对象)包含不确定的值。

UB!

事实上,编译器用零来初始化你,并不意味着什么,今天它初始化,明天,在下一次更新后....。

 
Vladimir Simakov #:

阅读。

值初始化的效果是。

1)如果T是一个没有默认构造函数 或有用户提供或删除的默认构造函数类类型,则对象被默认初始化
2如果 T是一个具有默认构造函数的类类型,该构造函数既不是用户提供的,也不是被删除的(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),则对象零初始 化,并且检查默认初始化的语义约束,如果 T有一个非实质性的默认构造函数,则对象默认初始化
3)如果T是一个数组类型,数组的每个元素都被初始化了
4) 否则,该对象零初始化


阅读关于default-initialized。

  • 如果 T是一个(可能是cv限定的非POD(直到C++11)的 类类型,那么构造函数将被考虑,并针对空参数列表进行重载解析。所选择的构造函数(是默认的构造函数 之一)被调用,以提供新对象的初始值
  • 如果 T是一个数组类型,数组的每个元素都被默认初始化。
  • 否则,不进行初始化:具有自动存储期限的对象(及其子对象)包含不确定的值。

UB!

事实上,编译器用零来初始化你,并不意味着什么,今天它初始化,明天,在下一次更新后....。

我的帖子 "忘记添加.... "是作为前一个帖子的补充写的。

关于交易、自动交易系统和测试交易策略的论坛

mql5语言的特殊性,技巧和窍门

mktr8591, 2021.11.18 18:15

@A100




如果你还记得mql是从C++催生出来的,这两个例子(它们的对应物)在那里都很好用,因为这些类中没有构造函数(即有一个隐式构造函数)。

  • 声明ClassX x[n]={};的结果是对数组的每个元素进行值初始化
  • 如果ClassX没有自定义构造函数(但有一个默认的未设置的构造函数),那么类对象的零初始化就完成了--不管是否有私有字段。
  • 但如果有常量字段,默认的ktor将被隐式删除,所以编译器错误。

在C++中的例子。

#include <iostream>
using namespace std;

class X
{
    int a;
    public:
    int get(){return a;}

    //X(){}   //так массив x не обнуляется
    //а если нет конструктора - то обнуляется
};

int main()
{
    X x[10]={};
    for (int i=0; i<10;i++)   cout<<x[i].get()<<endl;
}

因此,如果结构/类中没有常量字段,那么逻辑是正确的。


它处理了某种情况--当一个类没有用户构造函数,而有一个隐式构造函数没有被删除。在这种情况下,你引用的第1点是不合适的。

"2如果 T是一个具有默认构造函数的类类型,该构造函数既不是用户提供的,也不是被删除的(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),则对象零初始化,并且检查默认初始化的语义约束,如果 T有一个非实质性的默认构造函数,那么该对象就是默认初始化 的;"。


因此,这一切都配合在一起。

 
Vladimir Simakov #:

阅读。

值初始化的效果是。

1)如果T是一个没有默认构造函数 或有用户提供或删除的默认构造函数类类型,则对象被默认初始化
2如果 T是一个具有默认构造函数的类类型,该构造函数既不是用户提供的,也不是被删除的(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),则对象零初始 化,并且检查默认初始化的语义约束,如果 T有一个非实质性的默认构造函数,则对象默认初始化
3)如果T是一个数组类型,数组的每个元素都被初始化了
4) 否则,该对象零初始化


阅读关于default-initialized。

  • 如果 T是一个(可能是cv限定的非POD(直到C++11)的 类类型,那么构造函数会被考虑,并针对空参数列表进行重载解析。所选择的构造函数(是默认的构造函数 之一)被调用,以提供新对象的初始值
  • 如果 T是一个数组类型,数组的每个元素都被默认初始化。
  • 否则,不进行初始化:具有自动存储期限的对象(及其子对象)包含不确定的值。

UB!

事实上,编译器用零来初始化你,并不意味着什么,今天它初始化,明天,在下一次更新后....。

Oops. misread it.在这种情况下。

2如果T是一个具有默认构造函数的类类型,它既不是用户提供的,也不是被删除的(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),那么对象零初始化和默认初始化的语义约束被检查,如果T有一个非实质性的默认构造函数,那么该对象就是默认初始化
 
fxsaber #:

很好。事实证明,归零是在构造函数之前进行的,所以一切都很正确。谢谢你!

以防万一--这只是针对静态的(这都是关于C++的)。对于局部变量,如果有一个自定义的k-tor,就没有归零的问题。
 
fxsaber #:

我还没有见过for语句中的无效函数调用。其他的变种是很常见的。

你可以在for语句的第3个参数中写任何你喜欢的东西,事实上,for语句可以用{.....}代替if()语句。

SZZ: 我还见过这样的宏,如

do
{
.....
}while(0)
 
Igor Makanu #:

你可以把任何你喜欢的东西写进for语句的第3个参数,事实上,for语句可以用{.....}代替if()语句。

SZZ: 我还见过这样的宏,如

去掉分号,否则就失去了整个意义)))

 
Vladimir Simakov #:

移除分号,否则所有的意义都会丧失))))。

是的,没错--这个例子在宏中调用宏时要放上;,我不常使用宏--没有练习过。