#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という子孫を1つ追加し、スイッチでケースを1つ追加するだけでよいのです。つまり、入力データを統一することで、プログラム本編での編集を回避しているのです。
もちろん、これは作業アルゴリズムが様々なタイプを入力として受け入れる場合にのみ適切である。1種類しかなければ、すべて意味がない。
教科書では、ポリモーフィズムとの関連でこのような例が挙げられている。
ひとつだけわからないことがあるんです。子関数オブジェクト、すなわち派生メソッドCCircleと CSquareを 呼び出しに使えば、ベースクラスでの宣言をバイパスしてGetArea() 面積を計算することができます。つまり、ベースクラスでは仮想関数を一切作らず、派生メソッドでは単純なメソッドを作る、それだけです。では、なぜ仮想関数が必要なのでしょうか?
適切かつ論理的な例で、仮想関数が何らかの利益をもたらすことがわかるのは興味深いことです。なぜなら、私が見たものは、少なくとも私にとっては論理的ではなかったからです。同じように理解したいと思います。
ここで簡単な例を挙げてみましょう。
GetArea()関数がどの図形に対して呼び出されたかを知らずに使用しています。このセッターをクラスで持っています。
コンパイラは一般にこのColorBySend 配列への要素の 割り当てをこのように扱っています。
これと何の関係があるのですか?本当に要素ごとに値を割り当てる必要があるのでしょうか?リストとして行うことはできないのでしょうか?何に関連しているのか?何しろ、教科書でも課題がそうなっているのですから...。このセッターをクラスで持っています。
コンパイラはこのようにColorBySend 配列への要素の割り当てを一般的に悪用しています。
これと何の関係があるのですか?本当に要素ごとに値を割り当てる必要があるのでしょうか?リストとして行うことはできないのでしょうか?それと何の関係があるのですか?何しろ、教科書でも課題はこうなっているのですから...。、コンパイラが理解できない変数式になっています。嗚呼。