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

 
Nikolai Semko # : https://www.mql5.com/ru/forum/170952/page243#comment_52244665

这里怎么了?
你可能是在看旧信息,懒得往前看。

对不起,可能是因为谷歌自动翻译

 

图片中的问题是

代码:
class C_AO_Agent
{
public:
    double c[];
    double f;
};

class C_AO
{
public:
    double cB[];
     C_AO_Agent *a;

    virtual void Init() { }
};

class C_Agent : public C_AO_Agent
{
public:
    double g;
    
    class ad
    {
    
    };
};

class C_P : public C_AO
{
public:
    void Init()
    {
      a = new C_Agent;
      a.f = 5;
    }
};

void OnStart()
{
    C_AO *ao;
    ao = new C_P;
    ao.Init();
}
 
Andrey Dik #:

图片中的问题是

代码:

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

mql5 语言的特点、微妙之处和工作技巧

Andrey Dik, 2024.02.16 06:05

class C_AO_Agent
{
public:
    double c[];
    double f;
};

class C_AO
{
public:
    double cB[];
     C_AO_Agent *a;

    virtual void Init() { }
};

class C_Agent : public C_AO_Agent
{
public:
    double g;
    
    class ad
    {
    
    };
};

class C_P : public C_AO
{
public:
    void Init()
    {
      a = new C_Agent;
      a.f = 5;
    }
};

void OnStart()
{
    C_AO *ao;
    ao = new C_P;
    ao.Init();
}

基类无法访问子类的字段。

 
fxsaber #:

基类无法访问子类字段。

是的,但我是这样打败它的:

class C_AO_Agent
{
public:
    double c;
    double f;
};

class C_AO
{
public:
    double cB[];
     C_AO_Agent *a;

    virtual void Init() { }
};

class C_Agent : public C_AO_Agent
{
public:
    double g;
    
    class ad
    {
    
    };
};

class C_P : public C_AO
{
public:
    void Init()
    {
      a = new C_Agent;
      C_Agent *agent = (C_Agent*)a; // Приведение типов
      agent.f  = 5;
      agent.g  = 7;                 //теперь есть доступ к g!!!
      agent.c  = 8;
    }
};

void OnStart()
{
    C_AO *ao;
    ao = new C_P;
    ao.Init();
    
    //тут нам нужен доступ только к f и c
    Print (ao.a.f);
    Print (ao.a.c);
    
    // Удаление объектов
    delete ((C_Agent*)ao.a);
    delete ao;
}
这就是所需的工作版本。
 
Andrey Dik #:
是的,但以这种方式击败: 是所需的工作版本。

它的错误很多。
在 OnStart 方法中,您应该指定一个只有在 C_P 类的 Init 方法中才知道的类型。
我认为最好为 C_P 添加 Deinit()。
 
Sergey Gridnev #:
这是一个非常严重的错误。
在 OnStart 方法中,必须指定只有在 C_P 类的 Init 方法中才知道的类型。
我认为最好为 C_P 添加 Deinit()。
请举例说明,任何人都可以冒犯艺术家)
 
Andrey Dik #:
举例说明
class C_AO_Agent
{
public:
    double c;
    double f;
};

class C_AO
{
public:
    double cB[];
     C_AO_Agent *a;

  C_AO( void ) : a(NULL) {}
  
  ~C_AO( void )
  {
    this.Init();
  }

    virtual void Init()
    {
      if (::CheckPointer(this.a) == POINTER_DYNAMIC)
        delete this.a;
    }
};

class C_P : public C_AO
{
protected:
  class C_Agent : public C_AO_Agent
  {
  public:
      double g;
      
      class ad
      {
      
      };
  } *agent;
  
public:
    C_P( void ) : agent(NULL) {}
    
    virtual void Init()
    {
      this.C_AO::Init();
            
      this.agent = new C_Agent;
      this.a = this.agent;
    }
};

void OnStart()
{
    C_AO *ao;
    ao = new C_P;
    ao.Init();
    
    //тут нам нужен доступ только к f и c
    Print (ao.a.f);
    Print (ao.a.c);
    
    // Удаление объектов
    delete ao;
}
 
Andrey Dik #:
举个例子,任何人都可以冒犯艺术家)。
举什么例子?
如何在一个类中添加 void Deinit(void) 方法,在 a 是对象的有效指针时调用 delete(a)?
或者如何在 OnStart() 中编写 ao.Deinit()?
;)
 
Sergey Gridnev #:
什么示例?
如何在一个类中添加 void Deinit(void) 方法,在 a 是对象的有效指针时调用 delete(a)?
或者如何在 OnStart() 中编写 ao.Deinit()?
;)

我们的任务是获取对象的访问权限,而不是组织对象的正确删除。删除总是比创建容易))

 
fxsaber #:
谢谢,这很有趣。