是否有可能在MQL4中实现一个单子模式。 - 页 9

 
hoz:

我是这样做的。

但由于某些原因,在编译时出现了很多错误。怎么了?

例如,试图通过Myers将一个相当简单的Singleton转移到MQL4++,可能会是这样的。

#property strict

/******************************************************************************/
class Symbol_Properties {
private:
   // Реализация технической части singleton'а
  /******************************************************************************/
public: // Вечно в этом MQL4++ что-то не работает: 'Symbol_Properties::Symbol_Prope…' - cannot call private member function
  Symbol_Properties() {};
private: // Восстанавливаем private
  Symbol_Properties(const Symbol_Properties &p);
  void operator =(const Symbol_Properties &);

public:
  static Symbol_Properties *singleton() {
    static Symbol_Properties sp;
    return GetPointer(sp);
  }

  // Пользовательская часть singleton'а
  /******************************************************************************/
  datetime    gdt_Quote;           // Время поступления последней котировки
  double      gda_Price [2];       // Текущие рыночные цены (0 - Bid, 1- Ask)
  double      gd_Spread;           // Размер спреда в пунктах
  double      gd_Swap;             // Своп
  double      gd_Comission;        // Комиссия
  double      gd_Pt;               // Величина одного пункта
  int         gi_Digits;           // Количество знаков в цене после запятой
  int         gi_StopLevel;        // Минимально-допустимый уровень стоп-лосса/тейк-профита в пунктах
  int         gi_FreezLevel;       // Уровень заморозки ордеров в пунктах
};

/******************************************************************************/
void change() {
  Symbol_Properties *p = Symbol_Properties::singleton(); // Получение singleton'а

  p.gdt_Quote = TimeCurrent();
  p.gda_Price[0] = Bid;
  p.gda_Price[1] = Ask;
}

/******************************************************************************/
void OnStart() {
  Symbol_Properties *p = Symbol_Properties::singleton(); // Получение singleton'а

  Print("gdt_Quote = ", p.gdt_Quote, ", Price = ", p.gda_Price[0], "/", p.gda_Price[1]);
  change();
  Print("gdt_Quote = ", p.gdt_Quote, ", Price = ", p.gda_Price[0], "/", p.gda_Price[1]);
}

执行结果。

01:24:57 Script 3 EURUSDm,H1: loaded successfully
01:24:57 3 EURUSDm,H1: initialized
01:24:57 3 EURUSDm,H1: gdt_Quote = 1970.01.01 00:00:00, Price = 0.0/0.0
01:24:57 3 EURUSDm,H1: gdt_Quote = 2014.09.03 21:24:57, Price = 1.31461/1.3148
01:24:57 3 EURUSDm,H1: uninit reason 0
01:24:57 Script 3 EURUSDm,H1: removed

一个静态方法singleton()创建了一个 Symbol_Properties类型的静态变量,但在编译时产生了一个无效的默认构造函数调用访问错误,因为该方法虽然是静态的,但可以访问所有成员,包括私有的。因此,由于MQL4++实现中的错误,这个构造函数必须被放在公共的地方。如果他们解决了这个问题,我们就不用再做了。

执行的结果显示,在调用change()后,数据发生了变化。这间接表明change()函数在自身内部收到了同样在OnStart()中收到的同一个对象的地址。

由于MQL4++的错误,这根本不是Singleton,因为默认的构造函数是公开的,所以可以创建许多这样的对象。如果错误得到纠正,并且默认的构造函数被放置在私有部分后,它将成为MQL4++中Myers'Singleton的完整实现。

 
ALXIMIKS:

两天来,你还没有弄清楚静态在研究和课堂上的行为是不同的吗?

这些结构似乎取自于C,只是在继承性方面有一点提高。

至于班级,则是全面的。

正因为如此,你不必在结构中为静态变量保留空间

但你必须在课堂上保留空间,否则你就不会。

不是这样的,这个奇妙的MQL4++编译器的行为是不同的。只要你创建一个对象实例,行为就会 "对齐"。

#property strict

/******************************************************************************/
struct A {
  static int x;
};

/******************************************************************************/
void OnStart() {
  A y;
}

由于某些原因,它不能编译(第一和第三条是警告,但第二条是一个完整的错误)。

struct has no members, size assigned to 1 byte
unresolved static variable 'A::x'
variable 'y' not used

那么是否有必要在结构中保留 "静态变量的空间"?

而在下一个版本的终端/编译器中--会不会也是一样的(好吧,不急于在改变版本时修复之前写的一切)?

 
TheXpert:

我忘记了封装的问题。而且可以删除。而且这里没有恒定的指针)。事实上,单子并不是最好的模式。

而模板是好的,至少有些是。对于班级来说,可能只是一个梦想。



好吧,无论它是最坏的还是最好的,我都不会评判。

让我提醒这次讨论的参与者,上述的内存管理模式--自动、动态、静态、基于--并不适用于模板,无论OOP多么强大。

 
Так обязательно ли резервировать в структурах "место под static-переменную"?
"是",这只是一个观点,你也可以做 "不",但你不应该这样做。
 
simpleton:


现在,由于MQL4++的错误,这不是一个Singleton,因为可以创建许多这样的对象,因为默认的构造函数是公共的。如果错误得到纠正,并且默认构造函数被放置在私有部分,它将成为MQL4++中成熟的Singleton实现。


谢谢你,我不知道我可以在这里拿一个指针。

代码很乱,可以更简单,抱歉没有模板。

我不能把代码放进去(()。

类Singleton{

私下里。

Class SomeClass{

公众。

int a;

};

Singleton(){}。

~Singleton(){}。

公众。

静态SomeClass* Instance(){

静态的SomeClass a()。

返回GetPointer (a)。

}

};

空白的OnStart()

{

SomeClass* some_ptr = Singleton::Instance()。

some_ptr.a = 5;

Alert(some_ptr.a)。

}

 
ALXIMIKS:


谢谢你,不知道你可以在这里拿一个指针。

你在乱用代码,可以更简单,对不起,没有模板。

我无法让代码工作(()。

类Singleton{

私下里。

Class SomeClass{

公众。

int a;

};

Singleton(){}。

~Singleton(){}。

公众。

静态SomeClass* Instance(){

静态的SomeClass a()。

返回GetPointer (a)。

}

};

空白的OnStart()

{

SomeClass* some_ptr = Singleton::Instance()。

some_ptr.a = 5;

Alert(some_ptr.a)。

}

下面是Myers的C++代码。

class Singleton
{
private:
    Singleton() {}
    Singleton( const Singleton&);
    Singleton& operator=( Singleton& );
public:
    static Singleton& getInstance() {
        static Singleton  instance;
        return instance;
    }
};

而这里是同样的代码被移植到MQL4++中,这就是例子中类的技术部分。

class Symbol_Properties {
private:
   // Реализация технической части singleton'а
  /******************************************************************************/
public: // Вечно в этом MQL4++ что-то не работает: 'Symbol_Properties::Symbol_Prope…' - cannot call private member function
  Symbol_Properties() {};
private: // Восстанавливаем private
  Symbol_Properties(const Symbol_Properties &p);
  void operator =(const Symbol_Properties &);

public:
  static Symbol_Properties *singleton() {
    static Symbol_Properties sp;
    return GetPointer(sp);
  }

这里的 "巫术 "在哪里?

你的例子利用了MQL4++编译器的错误,特别是在OnStart()中使用SomeClass类型是不合适的,因为这是Singleton类的一个嵌套类型,而 "成人 "编译器会立即检测到错误。

try.cpp:33:9: error: unknown type name 'SomeClass'
        SomeClass* some_ptr = Singleton::Instance();
        ^

然而,这并不是一个关键点,因为可以正确地指定一个嵌套类型。更重要的是,SomeClass类型是在Singleton类的私有部分声明的,因此在OnStart()中使用SomeClass现在是根本性的错误,"成人 "编译器会立即报告。

try.cpp:33:20: error: 'SomeClass' is a private member of 'Singleton'
        Singleton::SomeClass* some_ptr = Singleton::Instance();
                   ^

除非MQL4++编译器修复了访问控制bacchanalia,否则你的实现将会工作。

 

1.Maerse,不是Maerse,如果代码在MQL中 工作并 正确的事情 而不在++中出错,这他妈的有什么关系。

2.你的代码是否做了它应该做的事?不,它没有。你已经明白了一切。

我的例子展示了MQL中错误的解决方法(关于C++)。 如果有些东西不方便,请看第1和第2点。

4.至于创建一个指向私有类的指针,是的,这是一个MQL错误,但没有自动识别类型,所以它能工作就好。\

(p.s. 我可能在牺牲汽车的情况下做得过头了,我应该检查一下)

5.在MQL中,我还没有找到任何方法来解除对一个指针的引用以获得一个对象,因此我认为私有的复制构造器和赋值运算符 是多余的。

试着使用它们,我会很高兴看到这种方式))

 
ALXIMIKS:

1.Maerse,不是Maerse,如果代码在MQL中没有错误地 工作和 它应该做的事,而不是在++中,这他妈的有什么关系。

2.你的代码是否做了它应该做的事?不,它没有。你已经明白了一切。

我的例子显示了MQL中对错误的处理(关于C++)。 如果有不方便的地方,请看第1和第2点。

4.至于创建一个指向私有类的指针,是的,这是一个MQL错误,但没有自动识别类型,所以它能工作就好。\

(p.s. 我可能在牺牲汽车的情况下做得过头了,我应该检查一下)

5.在MQL中,我还没有找到任何方法来解除对一个指针的引用以获得一个对象,因此我认为私有的复制构造器和赋值运算符是多余的。

试着使用它们,我会很高兴看到这种方式))

1.现在--确实如此,但不是这样的(以下解释)。

2.如果他们不修复它--它也不会做。而且根本不可能实施。

3.这不是绕过虫子的方法,而是利用。

4.有很多东西是不存在的。

5.这样的事情在这个版本中可能会发生,特别是,我想我之前已经闪过了,复制构造函数没有被合成,但这并不能保证它在未来的版本中不会开始合成。另一方面,申报它们的开销,我认为是可以忽略不计的。

现在来解释一下,为什么你的代码不仅有我在上一篇文章中提到的潜在问题,而且原则上不是单子,也不会是单子,以及他们是否修复了访问的bacchanalia。

#property strict

class Singleton{
private:
         class SomeClass{
         public:
            int a;
         };
        Singleton(){}
        ~Singleton(){}   
public:
        static SomeClass* Instance(){
                        static SomeClass a;
                        return GetPointer (a);
                }
        };
        int i;

void OnStart()
{       
        SomeClass* some_ptr = Singleton::Instance();
        SomeClass obj1;
        SomeClass obj2;

        obj1.a = 3;
        obj2.a = 7;

        some_ptr.a = 5;
        Print("some_ptr.a = ", some_ptr.a);          
        Print("obj1.a = ", obj1.a);          
        Print("obj2.a = ", obj2.a);          
}

这段代码执行得相当成功。

10:09:27 Script 3 EURUSDm,H1: loaded successfully
10:09:27 3 EURUSDm,H1: initialized
10:09:27 3 EURUSDm,H1: some_ptr.a = 5
10:09:27 3 EURUSDm,H1: obj1.a = 3
10:09:27 3 EURUSDm,H1: obj2.a = 7
10:09:27 3 EURUSDm,H1: uninit reason 0
10:09:27 Script 3 EURUSDm,H1: removed

你看到有多少个单子被成功地创造出来,而它们却只存在一次?

如果固定了访问权限,在这个意义上,你的代码会有什么变化吗?

它在我的代码中会改变吗?

你是否认为,你越是毫不掩饰地陈述,就越是真实?

 

是的,谢谢你的关注,你是对的,在这个变体中它也不是一个单子。

关于隐式构造函数和运算符--把它们显式化并尝试使用它们,在我看来,它们不会起作用,因为不可能取消对对象指针的引用。

为什么不工作,'ptr' - 不能调用受保护的成员函数

class smart_ptr{
            Singleton* ptr;
      public:        
            smart_ptr(Singleton* val): ptr(val){}          
            smart_ptr(): ptr(NULL){} 
            ~smart_ptr(){delete ptr;}
      };
 
ALXIMIKS:

是的,谢谢你的关注,你是对的,在这个变体中它也不是一个单子。

关于隐式构造函数和运算符--把它们显式化并尝试使用它们,在我看来,它们不会起作用,因为不可能取消对对象指针的引用。

为什么不工作,'ptr' - 不能调用受保护的成员函数

它似乎不起作用,这里还有许多错误。很遗憾,很少有人注意到这一点。我不想陷入争论,但实际上有一个巨大的区别。有些适用于C++结构的东西在MKL4中不起作用。但我将保持沉默......否则他们会开始问一些问题,比如。

"我为什么需要它"。

如果仅仅是这样,我就可以不进入未完成的教科书,而仅仅是在MKL4中写一些在C++中能用的东西,而不去想它们在这里是否能用。在这个阶段,我不需要其他东西...