Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>
enum ENUM_CLASS_TYPE
{
HUMAN,
ANIMAL,
CAR
};
class Community : public CObject
{
public:
ENUM_CLASS_TYPE TypeCommunity(){return type;}
protected:
Community(ENUM_CLASS_TYPE cType)
{
type = cType;
}
private:
ENUM_CLASS_TYPE type;
};
class Human : public Community
{
public:
Human() : Community(HUMAN){;}
int IQ(){return90;}
};
class Animal : public Community
{
public:
Animal() : Community(ANIMAL){;}
int CountLegs(){return4;}
};
class Car : public Community
{
public:
Car() : Community(CAR){;}
int Speed(){return20;}
};
voidOnStart()
{
CArrayObj elements;
CObject* object = NULL;
while(elements.Total() < 100)
{
switch(rand()%3)
{
case HUMAN:
object = new Human();
break;
caseANIMAL:
object = new Animal();
break;
caseCAR:
object = new Car();
break;
}
elements.Add(object);
}
while(elements.Total() > 0)
{
Community* AnyObject = elements.At(0);
switch(AnyObject.TypeCommunity())
{
case HUMAN:
{
Human* human = AnyObject;
printf("Element is Human, it's IQ is: " + (string)human.IQ());
break;
}
case ANIMAL:
{
Animal* animal = AnyObject;
printf("Element is anima, it has " + (string)animal.CountLegs() + " legs.");
break;
}
case CAR:
{
Car* car = AnyObject;
printf("Element is car. It has speed " + (string)car.Speed() + " km/h");
break;
}
}
elements.Delete(0);
}
}
一年级,二年级。不幸的是,没有 Community 中介是不行的,因为 MQL5 的类型控制极其薄弱。但是,如果我们有一个类似 EnumToString() 的 ClassToString 函数,一切都可以组织得更优雅、更轻松。
先生们,我们为什么不试着进行实质性讨论呢?:)
一个正确的表单不应该要求明确地实现一个新的类来用于一个任意的类。
因此,正确的实现应该依赖模板。
平心而论,我不确定这是否能在模板层面上实现。
但这其实与文章中的问题相去甚远。
一个正确的列表不应该要求明确实现一个新类才能用于任意类......
有条件地,CList 应包括不同类型的节点....
为什么?) 容器是一组同质的对象。
对象本身的差异可以通过对象内部的多态性 来实现,与列表无关。
为什么?容器是一组同质的对象。
对象本身的差异可以通过对象内部的多态性 来实现,与列表无关。
正确的表单不应要求明确实现一个新类,以便将其用于任意类。
因此,正确的实现应该依赖模板。
平心而论,我不确定这是否能在所介绍的模板级别上实现。
但这其实与文章中的问题相去甚远。
TheXpert 的建议似乎很明确。
如果我对他的想法理解正确的话,某个抽象列表的所有方法都应自动识别 "它的 "节点(这就是多态性)。
例如,文章中有用户类 CiSingleList(图 9)、CDoubleList(图 11)、 CiUnrollDoubleList(图 12)、 CiCircleDoubleList (图 13)。
因此,原则上所有这些方法都可以塞进一个类中。但我们必须对每个方法进行编码,使其在特定时刻能识别所处理的节点类型。这也需要资源...所以并非一切都那么一目了然....
很明显,一个特定的列表包含同质节点。我的意思是,该列表中节点之间的关系可能不同,这就需要为每种类型的节点创建不同的列表类型。如果能为不同类型的节点创建相同的列表类,那就太好了....。我个人还没有尝试过.....需要考虑更高层次的抽象.....
TheXpert 的建议似乎很明确。
如果我对他的想法理解正确的话,某个抽象列表的所有方法都应自动识别 "它的 "节点(这就是多态性)。
例如,文章中有用户类 CiSingleList(图 9)、CDoubleList(图 11)、 CiUnrollDoubleList(图 12)、 CiCircleDoubleList (图 13)。
因此,原则上所有这些方法都可以塞进一个类中。但我们必须对每个方法进行编码,使其在特定时刻能识别所处理的节点类型。而这也需要资源...所以并不是所有事情都一目了然
有什么需要编码的?
一年级,二年级。不幸的是,没有 Community 中介是不行的,因为 MQL5 的类型控制极其薄弱。但是,如果我们有一个类似 EnumToString() 的 ClassToString 函数,一切都可以组织得更优雅、更轻松。