MQL4:我们如何跨文件分隔 class 定义?
MQL4: How can we separate a class definition across files?
我希望能够在 MQL4 中跨文件拆分 类,即拆分为 include/.mqh 文件中的定义和 library/.mq4 文件中的实现。我们该怎么做 - 我不断收到编译错误(“'function_name' 必须有主体”)?
例如我可以在 https://docs.mql4.com/basis/oop/class_templates 获取代码的子集,并将定义放入 .mqh 文件中:
#import "library.ex4"
//+------------------------------------------------------------------+
//| Class for a free access to an array element |
//+------------------------------------------------------------------+
template<typename T>
class TSafeArray
{
protected:
T m_array[];
public:
//--- operator for accessing the array element by index
T operator[](int index);
};
#import
并将实现放入 .mq4 文件(称为 library.mq4):
#property library
//+------------------------------------------------------------------+
//| Receiving an element by index |
//+------------------------------------------------------------------+
template<typename T>
T TSafeArray::operator[](int index)
{
static T invalid_value;
//---
int max=ArraySize(m_array)-1;
if(index<0 || index>=ArraySize(m_array))
{
PrintFormat("%s index %d is not in range (0-%d)!",__FUNCTION__,index,max);
return(invalid_value);
}
//---
return(m_array[index]);
}
之前有人问过这个问题,但主要答案将定义和实现都放入了 .mqh 文件中:
What is the correct way to define MQL4 "#import of static class methods"?。有什么解决办法吗?
我找到的最佳答案是由 Ex Ovo Omnia 在 https://www.mql5.com/en/forum/157907#comment_3808727 指出的。
详细信息位于 https://www.mql5.com/en/articles/362#expclass 的第二部分(“2. Class 的隐藏实现的导出”)。请注意,如果您将扩展名更改为,则那里的文件也适用于 MQL4 .mq4 并更新#include / #import 语句。
总结:在包含文件中定义一个基/父class,然后在库文件中定义并实现一个派生/子class。在专家文件中,可以将指向基 class 的指针强制转换为派生 class 的指针,以使用隐藏的派生 class 方法。
感谢 Daniel Kniaz 对 CArrayObj class (https://www.mql5.com/en/docs/standardlibrary/datastructures/carrayobj) 的建议。我发现如果你希望使用所有元素都是相同类型的数组(例如整数元素的类似 ArrayList 的对象)或者如果它们遵循某些预定义结构(例如 CTrade)但如果你的数组有自定义多种不同类型的结构。
我希望能够在 MQL4 中跨文件拆分 类,即拆分为 include/.mqh 文件中的定义和 library/.mq4 文件中的实现。我们该怎么做 - 我不断收到编译错误(“'function_name' 必须有主体”)?
例如我可以在 https://docs.mql4.com/basis/oop/class_templates 获取代码的子集,并将定义放入 .mqh 文件中:
#import "library.ex4"
//+------------------------------------------------------------------+
//| Class for a free access to an array element |
//+------------------------------------------------------------------+
template<typename T>
class TSafeArray
{
protected:
T m_array[];
public:
//--- operator for accessing the array element by index
T operator[](int index);
};
#import
并将实现放入 .mq4 文件(称为 library.mq4):
#property library
//+------------------------------------------------------------------+
//| Receiving an element by index |
//+------------------------------------------------------------------+
template<typename T>
T TSafeArray::operator[](int index)
{
static T invalid_value;
//---
int max=ArraySize(m_array)-1;
if(index<0 || index>=ArraySize(m_array))
{
PrintFormat("%s index %d is not in range (0-%d)!",__FUNCTION__,index,max);
return(invalid_value);
}
//---
return(m_array[index]);
}
之前有人问过这个问题,但主要答案将定义和实现都放入了 .mqh 文件中: What is the correct way to define MQL4 "#import of static class methods"?。有什么解决办法吗?
我找到的最佳答案是由 Ex Ovo Omnia 在 https://www.mql5.com/en/forum/157907#comment_3808727 指出的。
详细信息位于 https://www.mql5.com/en/articles/362#expclass 的第二部分(“2. Class 的隐藏实现的导出”)。请注意,如果您将扩展名更改为,则那里的文件也适用于 MQL4 .mq4 并更新#include / #import 语句。
总结:在包含文件中定义一个基/父class,然后在库文件中定义并实现一个派生/子class。在专家文件中,可以将指向基 class 的指针强制转换为派生 class 的指针,以使用隐藏的派生 class 方法。
感谢 Daniel Kniaz 对 CArrayObj class (https://www.mql5.com/en/docs/standardlibrary/datastructures/carrayobj) 的建议。我发现如果你希望使用所有元素都是相同类型的数组(例如整数元素的类似 ArrayList 的对象)或者如果它们遵循某些预定义结构(例如 CTrade)但如果你的数组有自定义多种不同类型的结构。