巴解组织。应用问题 - 页 8

 
Interesting:

1.后裔功能不可用。我不知道是谁或如何做到的,但就我个人而言,我从来没有从数组中获得SetRadius()和SetSide()的权限。也许有办法用autogenous解决这个问题,但我想不用它。

2.也许我对指针的工作方式不正确,但我要么一直有泄漏,要么不得不在主要工作的区块中直接打出指针。

所有可用...我上面的帖子
 
equivalent23:

我可以给你举个例子吗?

只是我举的例子是从文档中摘出来的,不清楚应该如何操作......

这就是它的工作方式。但完全没有文件:/ (但我又一次在指针上进行了练习)

#property copyright "Ya"
#property link      "Ya"
#property version   "1.00"
//--- Базовый класс
class CShape
  {
protected:
   int               m_type;                // тип фигуры
   int               m_xpos;                // X - координата точки привязки
   int               m_ypos;                // Y - координата точки привязки
public:
   void           CShape(){m_type=0;};   // конструктор, тип равен нулю
   int            GetType(){return(m_type);};// возвращает тип фигуры
   virtual void           SetRadius(double r){return;};
   virtual void           SetSide(double s){return;};
   virtual double         GetArea(){return(0); }// возвращает площадь фигуры
  };
//--- производный класс Круг
class CCircle: public CShape          // после двоеточия указывается базовый класс,
  {                                      // от которого производится наследование 
private:
   double            m_radius;              // радиус круга

public:
   void           CCircle(){m_type=1; m_radius=10;};  // конструктор, тип равен 1 
   virtual void           SetRadius(double r){m_radius=r;};
   virtual double GetArea(){return(3.14*m_radius*m_radius);}// площадь круга
  };
//--- производный класс Квадрат
class CSquare: public CShape          // после двоеточия указывается базовый класс,
  {                                      // от которого производится наследование 
private:
   double            m_square_side;        // сторона квадрата

public:
   void            CSquare(){m_type=2;}; // конструктор, тип равен 2 
   virtual void            SetSide(double s){m_square_side=s;};
   virtual double GetArea(){return(m_square_side*m_square_side);}//площадь квадрата
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CCircle *ci=new CCircle;
   CSquare *sq=new CSquare;
   CShape  *shapes[2];                       // массив объектов CShape

   shapes[0]=ci;
   shapes[1]=sq;
////---зададим уникальные свойства объектов
   shapes[0].SetRadius(5.0);
   shapes[1].SetSide(4.0);
   for(int i=0; i<2;i++)
     {
      //--- тип и площадь фигуры
      Print("Объект типа "+shapes[i].GetType()+" имеет площадь "+shapes[i].GetArea());
     }
 
AlexSTAL:

执行。

可以做得更简单...虚拟化。


这不是我在说的事。我们不是在谈论仅仅使用指针,我们是在谈论这些指针的数组,有一个基类类型。

CShape ArrShapes[10]; // массив объектов CShape

不管是简单的数组还是指针数组,都不重要,只有基类中写的东西才有效,才可以用。

或者说我错过了什么。

例如,一个稍加修改的基类(被设计成结构体)

//class CShape
struct CShape
//Базовый класс
{  
protected: 
int            m_type;                // тип фигуры
int            m_xpos;                // X - координата точки привязки
int            m_ypos;                // Y - координата точки привязки

public:
void           CShape(){m_type=0;};   // конструктор, тип равен нулю
int            GetType(){return(m_type);};// возвращает тип фигуры

void           SetPosX(int s){m_xpos=s;};
int            GetPosX(){return(m_xpos);};

void           SetPosY(int s){m_ypos=s;};
int            GetPosY(){return(m_ypos);};

double GetArea(){return (0); }// возвращает площадь фигуры

};

如果我们把这些东西都塞进数组,我们至少可以获得基类中声明的功能。

问题是,如果数组是基类类型(即数组是CShape类型),如何通过子代访问功能?

Когда нужно использовать указатели в MQL5
Когда нужно использовать указатели в MQL5
  • 2010.03.25
  • MetaQuotes Software Corp.
  • www.mql5.com
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
 
Interesting:

这不是我在说的事。我们不是在讨论简单地使用指针,而是讨论这些指针的数组与基类类型。

问题是,如果数组是基类类型(即数组是CShape类型),如何通过子代访问该功能?

我在最后一页上写了如何。

class CBase
  {
public:
   void m_radius() {Print("CBase");}
  };

class CTest : public CBase
  {
public:
   void m_radius() {Print("CTest");}
  };

CBase* Base;

void OnStart()
  {
   Base = new CTest;
   Base.m_radius();
   ((CTest *)Base).m_radius();
   delete Base;
  }
 

同样的代码,只是用一个数组。

class CBase
  {
public:
   void m_radius() {Print("CBase");}
  };

class CTest : public CBase
  {
public:
   void m_radius() {Print("CTest");}
  };

CBase* Base[1];

void OnStart()
  {
   Base[0] = new CTest;
   Base[0].m_radius();
   ((CTest *)Base[0]).m_radius();
   delete Base[0];
  }
 
Yedelkin:

这就是它的作用。但完全脱离了文件的内容 :/

嗯,我的意思是一样的,你至少应该在一个基类中指定所有的函数(否则它们将无法访问)。
 
AlexSTAL:

执行。

对于这样的事情。

((CTest *)Base).m_radius();

应该随着键盘的没收而被撕掉。

在C++中,你可以用dynamic_cast在类的层次结构中移动,而且在那里也不喜欢。在MQL中,它可能会导致隐性崩溃,而这是不容易解决的,因为错误是在一个完全不同的地方。

因此,我强烈建议不要使用这种类型的转换。就是说,在所有。对祖先请,对孩子请。

 
TheXpert:

对于这样的事情。

你应该把你的手拿开,把你的键盘没收了。

在C++中,你可以使用dynamic_cast在类的层次结构中移动,而且那里也不喜欢。在MQL中,它可能会导致隐性崩溃,不容易解决,因为错误是在一个完全不同的地方。

因此,我断然建议不要使用这种转换。就是说,根本没有。请给祖先,不要给孩子。

回答的礼貌方式是什么....

如果程序员太笨,那么一个简单的1+1操作就会造成隐性崩溃....。

我想指出的是,MQL5不是C++...

这只是一种可能性,而不是一个应用问题....。

 
AlexSTAL:

同样的代码,只是用一个数组。


1.从祖先那里删除m_radius(),它不在例子中。:)而且你在OnStart()中也不会得到任何工作。

2.是否有其他地方可以放删除Base[0]行?比如,如果它不是一个脚本,而是一个猫头鹰,而我仍然需要数组中的数据。

我马上就有了内存泄漏。由于这个原因,我不得不改用结构...

 
Interesting:

1.删除m_radius(),它不存在于例子中。而在OnStart()中却没有得到任何工作。

2.我可以把删除Base[0]一行移到其他地方吗?比如说,如果它不是一个脚本而是一个猫头鹰,而我仍然需要数组中的数据。

我马上得到了一个内存泄漏。由于这个原因,我不得不改用结构...

1) 移除后,可以使用。

class CBase
  {
public:
  };

class CTest : public CBase
  {
public:
   void m_radius() {Print("CTest");}
  };

CBase* Base[1];

void OnStart()
  {
   Base[0] = new CTest;
   ((CTest *)Base[0]).m_radius();
   delete Base[0];
  }
2) 最主要的是在程序结束前删除它...但如果你在一个函数中创建了这个指针,你需要注意把它保存在一个全局位置......