我已获得以下代码:
/* 1 */ class Market {
/* 2 */ public:
/* 3 */
/* 4 */ double foo;
/* 5 */
/* 6 */ /*
/* 7 */ * Constructor:
/* 8 */ */
/* 9 */ Market() {
/* 10 */ foo = 2;
/* 11 */ }
/* 12 */ };
/* 13 */
/* 14 */ Market market; // GLOBALLY VISIBLE VAR
/* 15 */
/* 16 */ void OnInit() { // OnInit event-process
/* 17 */ market = new Market(); // <------------------- 17,10
/* 18 */ Print(market.foo);
/* 19 */ }
/* 20 */
/* 21 */ void OtherFunc() {
/* 22 */ Print(market.foo);
/* 23 */ }
但是,当我尝试编译时,我遇到了以下错误:
test.mq4(17,10):
error 280:
&#39; =&#39; - 需要对象
基本上我正在计划创建一个对象实例并接收指向它的指针,所以我可以在代码中全局使用它。
我已经检查了MQL4
docs page关于课程的内容,但它对我没有帮助。
我还尝试将课程分配为:
Market *market = new Market();
然后我将第一行中的变量声明为:
Market market;
然后我收到了这个警告:
test.mq4(17,11):
warning 62:
宣布&#39;市场&#39;在第14行隐藏全球声明
并且文件编译,但我不想隐藏全局声明(因为它在其他函数中不可用),我想将一个对象实例分配到全局声明,所以我可以在整个代码中打印对象的变量。
我该怎么做?
答案 0 :(得分:1)
MQL4
第一个建议,从不依赖网络资源,始终检查自动更新IDE
- Help
。即便这样也不包含100%正确的文本/代码样本,但它比过时的网络文本更接近实际的编译器语法。
下一个建议,始终记住 MQL4
不是C
语言 - 奇怪的差异可能会扼杀其他聪明的想法。
对象创建操作员
new
new
运算符会自动创建相应大小的对象,调用对象构造函数并返回descriptor
创建的对象。如果失败,操作员将返回null descriptor
,可与NULL
常数进行比较。
new
运算符只能应用于class
个对象。它不能应用于结构。
对象指针
在MQL4
中,有可能动态创建复杂类型的对象。这是由new
运算符完成的,该运算符返回所创建对象的descriptor
。Descriptor
大8字节。从语法上讲,MQL4
中的对象描述符与C++
中的指针相似。
的实施例强>
MyObject* hobject= new MyObject();
与C++
相比,上面示例中的hobject
变量不是指向内存的指针,而是而非对象{{1 }} 即可。此外,在descriptor
中,函数参数中的所有对象必须通过引用传递。
使用上面的内容, MQL5
应该在全局范围内可见,假设它的声明在适当的位置,在任何系统事件处理程序/用户定义的代码启动之前(和确定,条件是在代码的任何较低级别范围内都没有发生名称屏蔽。)
在接触到超过hobject
hundreds man*years
的实践经验之后,所有高级解决方案都开始被设计为分布式框架,而不是必须继续作为语言不规范和语法蠕动的受害者。人们可能会认为这比将一些非常多的软件工程投入到生态系统中更为安全,其变化速度更快,而重复的代码库重新设计的经济性/性能可能会设法保持移动的沙子的速度。
无论如何: 欢迎加入
的狂野世界MQL4
答案 1 :(得分:0)
全局变量的声明应如下所示:
Market *market;
然后初始化课程(例如在OnInit()
中)你应该这样做:
market = new Market();
然后打印类变量(例如market.foo
)或照常调用方法(例如market.Foo()
)。
答案 2 :(得分:0)
故事中更重要的部分:
class
语法为 O 对象的非常重要的概念提供了方法 - O riented- D 设计思维模式。这里的对象边界,作为一个主要的保护屏障,而不仅仅是下一个语法 - 糖玩具(虽然一些语言确实强制执行这种主要的访问屏障保护,保存对象的内部世界绝对隔离任何尝试外部尝试“直接”与类实例变量进行交互(例如 SmallTalk
这样做,在优秀的水平上)其他一些语言,开始他们的首次访问OOP领域一些非凡的几十年后,在心理概念中没有表现出这样的清晰度,并且可能允许“混合” - 访问(这可能并且确实混淆了很多关于碰撞编程实践,那种绕过原来的主要 OOD架构的好处 - 编程/测试团队一方面面临全部风险。)
// DEMO GetFoo:
public: double DEMO_GetFoo(){ return( aClassVARIABLE_foo );
}
甚至直接打印<class-method>
// DEMO PrintActualFooVALUE:
public: void PrintActualFooVALUE(){ PrintFormat( "Value of foo == %23.10f",
aClassVARIABLE_foo
);
}
除了普遍允许的公共许可证通过赤裸裸的(自由暴露的)private: double aClassVARIABLE_foo;
破坏珍贵的物品玩具之外,还有更多的东西来保护public: double foo;
免受外部世界的侵害。
BEST PRACTICE: KEEP THE BENEFITS OF THE CORE MOTIVATION FOR OOD
如果有人这样做,则宁愿避免这种危险并调整自己的OOD工艺。
为什么?为了学术上的OOD纯度?
No。
第一需要在class
中更改一个不重要的实现细节将教导一个,为什么对象的内部世界和外部对象现实的外部世界的应有的分离是重要。
通过<class-methods>
访问完全阻止并主要避免修改后的class
权利之外的任何代码库影响,因为访问<class-methods>
反映了&amp;相应地调解所有内部变化,而外部世界并不需要知道(仅假设double
) {{1}的真实内部类表示的详细信息或者需要处理的更复杂的东西。
foo
,但代码public: <class-variable>
根据时间流程重新排序[ MT4终端]的结果
//+------------------------------------------------------------------+
//| ___StackOverflow_OOP_class_public_variable_DEMO.mq4 |
//| Copyright © 1987-2016 [MS] |
//| nowhere.no |
//+------------------------------------------------------------------+ >>> http://stackoverflow.com/questions/37368437/how-to-initialize-a-class-instance-and-print-its-public-variable
#property copyright "Copyright © 1987-2016 [MS]"
#property link "nowhere.no"
#property version "1.00"
#property strict
class DEMO_Class_Market {
// public:
private:
double aClassVARIABLE_foo;
// DEMO GetFoo:
public: double DEMO_GetFoo(){
return( aClassVARIABLE_foo );
}
// DEMO ChgFoo:
public: double DEMO_ChgFoo( double aNewVALUE_to_SET = EMPTY_VALUE ){
double aTempRetVALUE = aClassVARIABLE_foo;
aClassVARIABLE_foo = aNewVALUE_to_SET;
return( aTempRetVALUE );
}
// DEMO_<Constructor>:
DEMO_Class_Market(){
PrintFormat( "DEMO_Class_Market::<Constructor> has initially seen a variable foo == %23.10f", aClassVARIABLE_foo );
aClassVARIABLE_foo = 2.;
PrintFormat( "DEMO_Class_Market::<Constructor> has set a new value into var. foo == %23.10f", aClassVARIABLE_foo );
}
// DEMO_<Destructor>:
~DEMO_Class_Market(){
PrintFormat( "DEMO_Class_Market::<Destructor> has seen a current value of a foo == %23.10f", aClassVARIABLE_foo );
}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(){
DEMO_Class_Market anInstanceOfMARKET;
double anExternalQueryForClassVariableVALUE = EMPTY;
int aReturnCODE = GetClassInstancePublicVariableVALUE( anInstanceOfMARKET, anExternalQueryForClassVariableVALUE );
PrintFormat( "1.st call to GetClassInstancePublicVariableVALUE( anInstanceOfMARKET, ... ) function. The actual call returned [aReturnCODE == %d ], the anExternalQueryForClassVariableVALUE is == %23.10f", aReturnCODE, anExternalQueryForClassVariableVALUE );
aReturnCODE = ChgClassInstancePublicVariableVALUE( anInstanceOfMARKET, 6666.6666, anExternalQueryForClassVariableVALUE );
PrintFormat( "1.st call to ChgClassInstancePublicVariableVALUE( anInstanceOfMARKET, 6666.6666 ) function. The actual call returned [aReturnCODE == %d ], the returned previous value of a class-[private] variable was == %23.10f", aReturnCODE, anExternalQueryForClassVariableVALUE );
aReturnCODE = GetClassInstancePublicVariableVALUE( anInstanceOfMARKET, anExternalQueryForClassVariableVALUE );
PrintFormat( "2.st call to GetClassInstancePublicVariableVALUE( anInstanceOfMARKET, ... ) function. The actual call returned [aReturnCODE == %d ], the anExternalQueryForClassVariableVALUE is == %23.10f", aReturnCODE, anExternalQueryForClassVariableVALUE );
}
//+------------------------------------------------------------------+
#define RET_OK 0
#define RET_ERROR EMPTY
#define VAL_ERROR EMPTY_VALUE
//+------------------------------------------------------------------+
int GetClassInstancePublicVariableVALUE( DEMO_Class_Market &aClassINSTANCE, // |-> DEMO_Class_Market INSTANCE = <aClassINSTANCE> of a type DEMO_Class_Market
double &aDoubleVALUE // <=| returns RESULT = ???.???
){
aDoubleVALUE = aClassINSTANCE.DEMO_GetFoo(); // STOR <class-method> RET VALUE IN RESULT
return( RET_OK ); // FLAG RET_OK in JIT/RET
}
//+------------------------------------------------------------------+
int ChgClassInstancePublicVariableVALUE( DEMO_Class_Market &aClassINSTANCE, // |-> DEMO_Class_Market INSTANCE = <aClassINSTANCE> of a type DEMO_Class_Market
double const aNewDoubleVALUEtoSET, // |-> a value to SET
double &aReplacedVALUE // <=| returns an OLD value
){
aReplacedVALUE = aClassINSTANCE.DEMO_ChgFoo( aNewDoubleVALUEtoSET ); // CHNG NEW VALUE IN VARIABLE via <class-method>, RET OLD VALUE
return( RET_OK ); // FLAG RET_OK in JIT/RET
}
//+------------------------------------------------------------------+
可以通过互斥(un)评论前者和后者的声明实例来测试两种声明备选方案。
2016.11.03 14:35:37.655 Script ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: loaded successfully
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: initialized
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: DEMO_Class_Market::<Constructor> has initially seen a variable foo == 0.0000000000
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: DEMO_Class_Market::<Constructor> has set a new value into var. foo == 2.0000000000
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: 1.st call to GetClassInstancePublicVariableVALUE( anInstanceOfMARKET, ... ) function. The actual call returned [aReturnCODE == 0 ], the anExternalQueryForClassVariableVALUE is == 2.0000000000
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: 1.st call to ChgClassInstancePublicVariableVALUE( anInstanceOfMARKET, 6666.6666 ) function. The actual call returned [aReturnCODE == 0 ], the returned previous value of a class-[private] variable was == 2.0000000000
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: 2.st call to GetClassInstancePublicVariableVALUE( anInstanceOfMARKET, ... ) function. The actual call returned [aReturnCODE == 0 ], the anExternalQueryForClassVariableVALUE is == 6666.6666000000
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: DEMO_Class_Market::<Destructor> has seen a current value of a foo == 6666.6666000000
2016.11.03 14:35:37.655 ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: uninit reason 0
2016.11.03 14:35:37.655 Script ___StackOverflow_OOP_class_public_variable_DEMO XAUUSD,H1: removed
在实践中已经在上面发布的
. .. ... DEMO_Class_Market anInstanceOfMARKET; // DECLARE'd on a global scope //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart(){ // DEMO_Class_Market anInstanceOfMARKET; // DECLARE'd on a local scope ... .. .
代码中显示了,正如赏金推理段落中所要求的那样,
一个类实例可以可以自由附加到全局作用域或本地作用域中存在的MQL4
变量。
如果需要执行某些特定于上下文的初始化在对代码执行访问MQL4
事件处理程序时,可能会设计一个额外的(几乎是pythonic:o)) { {1}}OnInit()
为此类特定情境/ MT4状态感知<class-method>
获得更多控制级别public: void __init__( ... ){ ... }
期间的初始化自定义,并在[MetaTrader Terminal 4]图表详细信息已知并且其参数和其他数字内容已经从<class-instance> >OnInit()
-code(目前还没有保证,类实例化过程正确发生在可用于全球范围定义的地方的声明代码中。)