错误、漏洞、问题 - 页 1183

 
Zeleniy:

测试专家顾问 时,它产生了一个错误

为OrderSend函数提供了无效的外差。

OrderSend错误4107

我怎样才能在不进入代码的情况下修复它?

在设置中尝试增加或减少利润。
 
mql5:
ZeroMemory函数不能用于此对象。

我明白了,但为什么编译器不是在使用ZeroMemory 的地方显示这个错误,而是在定义类的地方显示这个错误呢? 这让人困惑。我已经绞尽脑汁想知道错误是什么以及它的位置。 请确保错误显示在正确的位置。 例如,当复制一个包含不允许复制的项目的对象时,错误正好发生在复制的那一行,而不是在类的某个地方。

 
meat:

说到这一切的实际情况,我已经遇到了一个问题。这段代码使用的是静态对象。然后我决定用动态的取代其中的一些。结果,比较和赋值操作开始以相当不同的方式工作。而这个问题很难被发现,因为程序继续编译并正常工作,但不是以它应该的方式。

我并没有立即理解这个问题

class B {};

class A {
public:
        bool operator !=( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
        bool operator !=( B* b ) { Print( __FUNCTION__ ); return ( false );  }
        bool operator >>( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
        bool operator +( A* a )  { Print( __FUNCTION__ ); return ( false  ); }
        bool operator !()        { Print( __FUNCTION__ ); return ( true   ); }
};

void OnStart()
{
        A *a = new A;
        B *b = new B;
        if ( a != a ) Print( "1" );
        if ( a != b ) Print( "2" );
        if ( a >> a ) Print( "3" );
        if ( !a )     Print( "4" );
        delete( a );
        delete( b );
}
由此可以看出,(a != a)导致指针的比较,而(a >> a)导致调用运算符>>( A* )

这里面有一个矛盾。

你不能像其他重载运算符(除了==和!=)那样改变(a>>a)的行为,因为这将使下面的结构无法实现,因为你不能返回(A),而只能返回(A*)。

class A {
public:
        A *operator >>( string str ) { return ( GetPointer( this ) ); }
};

void OnStart()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили"; //множественное применение оператора <<
}

也将无法完全使用重载运算符,因为没有指针到对象的转换操作(*a)。

唯一要做的是改变(==和!=)行为

为了将指针(==和!=)相互之间以及与数字零进行比较(因为其他指针操作是没有意义的),应该引入一个特殊的函数,如(GetPointer)或明确向编译器指定一个类型转换

void OnStart()
{
        A *a = new A;
        B *b = new B;
        if ( ulong(a) != ulong(b) ) Print( "2" ); //хочу сравнить указатели
         if (       a  !=       b  ) Print( "2" ); //хочу вызвать operator !=( B* )

}

因此,全面使用重载运算符的可能性将被保留,上述矛盾将被消除。

一般规则的唯一合理例外应该是operator=(),因为


class A {
public:
        A *operator =( A* a ) { return ( GetPointer( this ) ); }
};
void OnStart()
{
        A *a = new A;
        a = a; //не должно трактоваться компилятором как вызов operator=( A* ),
                // а должно остаться как присваивание указателю значения
}
 
当然还有一个建议,就是至少对运算符使用(*a)--回到C++的符号中去
class A {
public:
        bool operator !=( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
};

void OnStart()
{
        A *a = new A;
        if (  a !=  a ) Print( 1 ); //сравнение указателей
        if ( *a != *a ) Print( 2 ); //вызов operator !=( A* )
}

将一下子消除所有的矛盾。

更正:实际上,矛盾只被部分地消除了,因为这样的符号(*a)并没有解决多次使用运算符的问题(现在成功地适用于所有的运算符,除了==和!=)--所以在平等/不平等的情况下比较指针的最好方法仍然是使用特殊函数--或者显式转换为ulong类型

 
A100,谢谢你的留言,我们会把它整理出来。
 
编译错误
class A {
public:
      A( int a1 ) : a3( a1 ) { }
  static int a2;
        int a3;
};
int A::a2 = 1;

void OnStart()
{
        int b = A::a2;  //нормально
        A t1( b );     //нормально
        A t2( A::a2 ); //ошибка компиляции
        A* t3 = new A( A::a2 ); //нормально
}
如果一个构造函数的静态成员参数(new除外)
 
编译器不允许在转移后的#define里面有注释
#define  f( x )                   \
        ( x != 0 &&  /*comment*/\ 
          x != 1 )

这很好,而这

#define  f( x )       \
        ( x != 0 &&  \ /*comment*/
          x != 1 )
编译错误
 

继续关于指针的主题,最好能在MQL中加入获取指针的标准操作符'&',这将比繁琐的GetPointer更方便和紧凑。因此,在我们的武器库中拥有*& 运算符,我们将能够明确地定义必要的操作。

if (&a==&b) Print("Указатели равны");
if (*a==*b) Print("Объекты равны");


还有更多关于这个安培字的内容。MQL缺乏对变量的引用,特别是考虑到对指针的有限使用(只对类对象)。 该函数经常需要访问一个深度嵌套的结构元素或一个多维数组。 我每次都要写出它的完整路径,这使得代码非常麻烦。你可以通过创建一个引用来简化事情,有时你只需要在本地 "改变 "一个变量的名字,以获得方便。 然而,我在这里解释什么呢? 每个人都已经知道使用引用是多么方便,但现在你必须使用#define来代替,这当然不是好事。

我们还需要有通过引用传递函数结果的能力,即 double& Func() { }。

 

Facebook最近出现了来自博客的帖子反向链接。

1

 
meat:

在指针的主题上,最好是在MQL中添加一个标准的操作符"&",它将比繁琐的GetPointer更方便和紧凑。因此,有了*& 运算符,我们可以毫不含糊地定义必要的操作。

只采用(*a)来指代成员函数并没有带来任何明显的优势,反而导致不可能简单清晰地多次应用运算符。

class A {
public:
        A *operator >>( string str ) { Print( __FUNCTION__); return ( GetPointer( this ) ); }
};

void OnStart()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили"; //простая и понятная запись

考虑到你的建议,试着重写它

void OnStart()
{
        A *a = new A;
        *(*(*(*a << "1234") << "мы") << "всю ночь") << "тусили"; //запутанная запись
}

你不能用对象本身代替指针,因为操作者<<(...)只能返回一个对象的指针。

哪些对指针的操作是无意义的?- 只有相互之间的比较和与一个数字的比较--因此,它们应该被忽略,放到一个特殊的函数中(例如,bool ComparePointer( a,b)),以便保留多次使用运算符的可能性,否则运算符重载本身将失去意义。