#property copyright"Copyright 2011, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"//+------------------------------------------------------------------+//| Класс-пример с несколькими типами доступа |//+------------------------------------------------------------------+class CBaseClass
{
private: //--- закрытый член недоступен из потомковint m_member;
protected: //--- защищенный метод доступен из базового класса и его потомковint Member(){return(m_member);}
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
private: //--- закрытый метод для присвоения значения члену m_membervoid Member(int value) { m_member=value;};
};
//+------------------------------------------------------------------+//| Производный класс с ошибками |//+------------------------------------------------------------------+class CDerived: public CBaseClass // public наследование можно не указывать, оно по умолчанию
{
public:
void Func() // определим в потомке функцию с обращениями к членам базового класса
{
//--- попытка модификации закрытого члена базового класса
m_member=0; // ошибка, закрытый член базового класса никому не доступен
Member(0); // ошибка, закрытый метод базового класса не доступен в потомках
关于构造函数的奇怪之处。
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
//--- Базовый класс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);};// возвращает тип фигурыvirtualdouble GetArea(){return (0); }// возвращает площадь фигуры
};
//--- производный класс Кругclass CCircle : public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_radius; // радиус кругаpublic:
void CCircle(){m_type=1;}; // конструктор, тип равен 1 void SetRadius(double r){m_radius=r;};
virtualdouble GetArea(){return (3.14*m_radius*m_radius);}// площадь круга
};
class CSquare : public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_square_side; // сторона квадратаpublic:
void CSquare(){m_type=2;}; // конструктор, тип равен 2 void SetSide(double s){m_square_side=s;};
virtualdouble GetArea(){return (m_square_side*m_square_side);}//площадь квадрата
};
//---- SetColorBySend
TradingFunc::SetColorBySend (constcolor fc_ColorSendBuy, // Цвет открытия ордера на покупкуconstcolor fc_ColorSendSell) // Цвет открытия ордера на продажу
{
ColorBySend [2] = {fc_ColorSendBuy, fc_ColorSendSell};
}
参数名称并不重要......不同的名称是有意义的,这样才不会与某些东西混淆......
你可以在函数声明中写一些值。
和函数本身的其他值
或者你可以在任何地方以相同的方式命名参数,以对代码编写者更方便的方式为准。
在同一本教科书中,遇到了这个代码。
关于构造函数的奇怪之处。
为什么这里有一个返回 运算符?这是我第一次看到在构造函数中使用这个操作符。事实上,构造函数被自动调用。而且无论如何都会有一个输出。这个操作符在构造器中有意义吗?
在同一本教科书中,遇到了这个代码。
关于构造函数的奇怪之处。
为什么这里有一个返回 运算符?这是我第一次看到在构造函数中使用这个操作符。事实上,构造函数被自动调用。而且无论如何都会有一个输出。这个操作符在构造器中有意义吗?
在这个例子中不需要,但在需要提前退出时可能会有复杂的初始化。
构造器和析构器是正常的函数。只有默认的构造函数和析构函数被自动调用。其他的是由用户调用的。
教科书中给出了这个与多态性有关的例子。
有一件事我不明白。如果我们使用子函数对象进行调用,即派生方法CCircle 和CSquare,那么GetArea() 面积就可以绕过基类中的声明进行计算。也就是说,根本不要在基类中创建虚拟函数,而在派生方法中创建一个简单的方法,仅此而已。那么,为什么我们需要一个虚拟函数呢?
看到一个充分的、符合逻辑的例子很有意思,你可以看到虚拟函数提供了一些好处。因为我看到的是不符合逻辑的,至少对我来说是这样。不过,我还是想了解一下。
教科书中给出了这个与多态性有关的例子。
有一件事我不明白。如果我们使用子函数对象进行调用,即派生方法CCircle 和CSquare,那么GetArea() 面积就可以绕过基类中的声明进行计算。也就是说,根本不要在基类中创建虚拟函数,而在派生方法中创建一个简单的方法,仅此而已。那么,为什么我们需要一个虚拟函数呢?
看到一个充分的、符合逻辑的例子很有意思,你可以看到虚拟函数提供了一些好处。因为我看到的是不符合逻辑的,至少对我来说是这样。我也想了解它。
这是理解多态性的最简单样本。为了迅速得到它。
有一些复杂的案件。你会在你需要的时候应用它。现在打扰是没有意义的。当任务完成后,你就得考虑一下了。
例如,我有一个基类,有所有可能的读/写接口。它也有私有的虚拟方法(共2个--读/写),将基类中的这个接口与派生类 联系起来。实际上,派生类可以是任何与文件有关的工作(文件、映射、通道、互联网)。每个派生类对这些虚拟方法的定义都不同,但所有的类都有与基类相同的接口。
教科书中给出了这个与多态性有关的例子。
有一件事我不明白。如果我们使用子函数对象进行调用,即派生方法CCircle 和CSquare,那么GetArea() 面积就可以绕过基类中的声明进行计算。也就是说,根本不要在基类中创建虚拟函数,而在派生方法中创建一个简单的方法,仅此而已。那么,为什么我们需要一个虚拟函数呢?
看到一个充分的、符合逻辑的例子很有意思,你可以看到虚拟函数提供了一些好处。因为我看到的是不符合逻辑的,至少对我来说是这样。我也想了解这一切。
我将尝试勾勒出一个小样本。
由于这个结构,我们不需要进入工作算法,这可能是非常大的和复杂的(这里的一切都被简化了),我们只需要在枚举中增加一个子代,m3,在开关中增加一个案例。也就是说,我们已经统一了输入数据,这将避免在程序的主要部分进行编辑。
当然,这只有在工作算法接受各种类型的输入时才会合适。如果只有一种类型,所有这些都是无用的。
教科书中给出了这个与多态性有关的例子。
有一件事我不明白。如果我们使用子函数对象进行调用,即派生方法CCircle 和CSquare,那么GetArea() 面积就可以绕过基类中的声明进行计算。也就是说,根本不要在基类中创建虚拟函数,而在派生方法中创建一个简单的方法,仅此而已。那么,为什么我们需要一个虚拟函数呢?
看到一个充分的、符合逻辑的例子很有意思,你可以看到虚拟函数提供了一些好处。因为我看到的是不符合逻辑的,至少对我来说是这样。我也想了解它。
这里有一个简单的例子。
我们使用GetArea()函数而不知道它是为哪个形状调用的。我在一个班里有这个设置者。
编译器一般是这样对抗这种向 ColorBySend 数组 分配元素 的。
这有什么关系呢?真的有必要逐个元素赋值吗?难道不可能以列表的形式进行吗?它与什么有关?毕竟,即使在教科书中也是这样分配的......我在一个班里有这个设置者。
编译器对这种将元素分配到ColorBySend 数组的做法发誓,一般来说是这样的。
这有什么关系呢?真的有必要逐个元素赋值吗?难道不可能以列表的形式进行吗?这与它有什么关系?毕竟,即使在教科书中也是这样分配的......是一个编译器无法理解的变量表达式。唉。