#property copyright "Ya"#property link "Ya"#property version "1.00"//--- Базовый класс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);};// возвращает тип фигурыvirtualvoid SetRadius(double r){return;};
virtualvoid SetSide(double s){return;};
virtualdouble GetArea(){return(0); }// возвращает площадь фигуры
};
//--- производный класс Кругclass CCircle: public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_radius; // радиус кругаpublic:
void CCircle(){m_type=1; m_radius=10;}; // конструктор, тип равен 1 virtualvoid 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 virtualvoid SetSide(double s){m_square_side=s;};
virtualdouble GetArea(){return(m_square_side*m_square_side);}//площадь квадрата
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
CCircle *ci=new CCircle;
CSquare *sq=new CSquare;
CShape *shapes[2]; // массив объектов CShape
shapes[0]=ci;
shapes[1]=sq;
////---зададим уникальные свойства объектов
shapes[0].SetRadius(5.0);
shapes[1].SetSide(4.0);
for(int i=0; i<2;i++)
{
//--- тип и площадь фигурыPrint("Объект типа "+shapes[i].GetType()+" имеет площадь "+shapes[i].GetArea());
}
//class CShapestruct CShape
//Базовый класс
{
protected:
int m_type; // тип фигурыint m_xpos; // X - координата точки привязкиint m_ypos; // Y - координата точки привязкиpublic:
void CShape(){m_type=0;}; // конструктор, тип равен нулюint GetType(){return(m_type);};// возвращает тип фигурыvoid SetPosX(int s){m_xpos=s;};
int GetPosX(){return(m_xpos);};
void SetPosY(int s){m_ypos=s;};
int GetPosY(){return(m_ypos);};
double GetArea(){return (0); }// возвращает площадь фигуры
};
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
1.子孫機能は使用できません。誰がどのようにしたのかわかりませんが、個人的にはArrayからSetRadius()とSetSide()にアクセスしたことがありません。もしかしたら、autogenousで解決する方法があるかもしれませんが、私はそれをせずにやりたいと思っています。
2.ポインターの扱いを間違えているのかもしれませんが、ずっと漏れがあるか、メインの作業が行われるブロックの中ですぐにポインターを打たないといけないんです。
例を挙げてみましょうか。
ただ、私が挙げた例はドキュメントから引用したもので、どのように動作するべきか明確ではありませんが......。
このような仕組みになっています。しかし、完全にドキュメントから外れている :/ (しかし、もう一度、ポインタで練習しました)
実行する。
は、もっとシンプルにできるはず...。仮想化
そういうことではないんです。単にポインターを使う という話ではなく、このポインターをベースクラスの型にして配列にするという話です。
単純な配列でもポインターの配列でも、ベースクラスに書かれているものだけが動作し、利用できるのです。
それとも何か見落としているのでしょうか。
例えば、ベースクラス(構造体として設計されている)を少し修正した場合
これを全部配列に詰め込めば、少なくともベースクラスで宣言されている機能にはアクセスできるようになる。
問題は、配列がベースクラス型(つまり、配列がCShape型)である場合に、どのように子孫の機能にアクセスするかということです。
ということではありません。単純にポインターを使う のではなく、このポインターをベースクラスの型にして配列にするという話です。
問題は、配列がベースクラス型(つまりCShape型)である場合に、子孫からどのように機能にアクセスするかということです。最後のページには、その方法を書きました。
同じコードで、配列だけです。
そういうことなんです。しかし、完全にドキュメントから外れている :/)
実行する。
このようなものに。
はキーボードの没収と一緒に引き剥がすべき。
C++では、dynamic_castでクラス階層を移動することができますが、これも好まれません。MQLの場合、バグが全く別の場所にあるため、簡単に解決できない暗黙のクラッシュが発生することがあります。
したがって、このタイプの変換を使用することは強くお勧めします。つまり、まったくです。ご先祖様にお願いします、子供たちにニ。
このようなものに。
手を離し、キーボードを没収してください。
C++では、dynamic_castを使ってクラス階層を移動することができますが、そこでも嫌われています。MQLでは、バグが全く別の場所にあるため、簡単に解決できない暗黙のクラッシュが発生することがあります。
したがって、このような変換を行うことは絶対に避けてください。つまり、全然ダメなんです。子供ではなく、ご先祖様にお願いします。
なんて答えるのが丁寧なんだろう...。
プログラマがあまりに馬鹿だと、単純な1+1の操作で暗黙のうちにクラッシュしてしまうことも......。
そして、MQL5はC++ではないことを指摘したい...。
これはあくまで可能性であって、応用の問題ではないのですが......。
同じコードで、配列だけです。
1.m_radius()を先祖から削除、例にはない。:)また、OnStart()では、これを使っての作業はありません。
2.他にdelete Base[0]の行を入れる場所はないのでしょうか?例えば、スクリプトではなくフクロウで、それでも配列のデータが必要な場合。
すぐにメモリーリークが発生しました。そのためにストラクチャーに乗り換えることになったのですが...。
1.m_radius() を削除、この例には存在しない。そして、OnStart()の中で、それを使って仕事をすることはありません。
2. delete Base[0]の行を別の場所に移動してもよいですか?例えば、スクリプトではなくフクロウで、それでも配列のデータが必要な場合。
すぐにメモリリークが発生しました。そのためにストラクチャーに乗り換えることになったのですが...。
1) 取り外すと、動作します。
2) プログラムが終了する前に削除することが主...しかし、このポインタを関数内で作成した場合、グローバルな場所に保存するように配慮する必要がある...。