面向对象OOP
一、面向对象 vs 面向过程
掌握这部分内容后,才能理解下一章“如何在一个EA中运行多个策略”。此前未讲解,是因为知识点较为抽象,但随着学员职业多样化,理解OOP的需求也在增加。科班出身的开发者可能更容易理解,非科班学员尽量掌握——OOP是强大的编程思想,能让代码更简洁、易复用、可扩展,但在EA这种小规模开发中场景较少,大家量力而行。
1. 面向过程
注重“过程”,将任务拆分为按顺序执行的方法,所有方法执行完毕即完成任务。
举例:开车
- 步骤:进入车辆 → 启动车辆 → 操作方向盘 → 行驶 → 停止 → 熄火 → 离开车辆
- 特点:按流程顺序调用独立方法。
2. 面向对象
注重“对象”,将任务涉及的事物抽象为对象,通过对象的方法协作完成任务。
举例:开车
- 对象:“人”和“车”
- 人拥有的方法:拧钥匙(启动车辆)、掌控方向盘
- 车拥有的方法:启动、行驶、停止
- 执行:创建对象 → 按顺序调用对象的方法
- 特点:先抽象对象,再通过对象交互解决问题。小规模问题中可能显得复杂,但适合复杂场景。
二、类(Class)的核心概念
类是OOP的基础,用于组织代码和数据。以下通过Strategy
类示例拆分知识点:
1. 类的结构
cpp
class Strategy : public CObject {
public:
long MagicNum; // EA编号
int SlType; // 止损方式
double SlParam; // 止损依据
string CurrentSymbol; // 当前品种
ENUM_TIMEFRAMES TimeFrame; // 时间周期
int BbPeriod; // bb周期
int slBBandsRange;
int efficiencyRatio;
Strategy(long InpMagicNum, int InpSlType, double InpSlParam,
string InpCurrentSymbol, ENUM_TIMEFRAMES InpTimeFrame,
int InpBbPeriod, int InpSlBBandsRange, int InpefficiencyRatio) {
MagicNum = InpMagicNum;
SlType = InpSlType;
SlParam = InpSlParam;
CurrentSymbol = InpCurrentSymbol;
TimeFrame = InpTimeFrame;
BbPeriod = InpBbPeriod;
slBBandsRange = InpSlBBandsRange;
efficiencyRatio = InpefficiencyRatio;
}
private:
int barsTotal;
double point;
double initBalance;
int handle;
double upperBuffer[];
double baseBuffer[];
double lowerBuffer[];
MqlTick currentTick;
int efficiencyRatioHandle;
double efficencyRatioBuffer[];
void OnInitEvent();
void OnTickEvent();
void OnDeinitEvent();
};
(1)成员变量
- 私有成员(
private
):仅类内部可访问 - 公有成员(
public
):类内外均可访问
(2)构造函数
- 特殊成员函数,创建对象(
new Strategy(...)
)时自动调用,用于初始化成员变量。 - 必须传递构造函数定义的参数,否则编译报错。
(3)成员函数
- 类内定义的函数,如
OnInitEvent
、OnTicketEvent
,实现具体逻辑。
2. 封装与访问权限
- 封装:将数据(成员变量)和操作(成员函数)封装到类中,通过
private
/public
控制访问。private
:隐藏内部细节,外部不可直接访问(需通过类内公共方法间接操作)。public
:对外暴露的接口,允许外部调用。
- 示例:
cpp
void test() {
Strategy * sg = new Strategy(102,4,10000,"AUDUSD.C",PERIOD_H3,2,2,2);
}
三、OOP在EA中的应用:封装策略
1. 传统EA vs 面向对象EA
- 传统EA:参数通过
input
修饰,全局变量直接暴露,逻辑分散在全局函数中。 - 面向对象EA:
- 将策略逻辑封装到类中,
input
参数转为类的公有成员或构造函数参数。 - 全局变量转为类的私有成员,通过类方法访问。
- 系统回调函数(如
OnInit
、OnTick
、OnDeinit
)转为类的成员函数,由外部调用。
- 将策略逻辑封装到类中,
2. 封装优势
- 代码复用:多个策略可继承同一个基类,复用公共逻辑。
- 多策略管理:一个EA中创建多个策略对象(如
Strategy1
、Strategy2
),独立管理各自状态和逻辑,避免全局变量冲突。
四、总结与建议
- 抽象概念:封装、继承、多态等需系统学习,短期理解困难很正常。
- 应用场景:若需在一个EA中运行多个策略,按固定模式封装类;若无此需求,可跳过OOP,优先掌握基础开发。
- 目标:通过类的封装,为后续多策略管理奠定基础,代码结构更清晰、可扩展。