OOP(オブジェクト指向プログラミング)に関する質問 - ページ 9

 
Integer:

つまり、new演算子でインスタンスを作成する必要があります。
ひとつだけわからないことがあるんです。新しい オペレーターを使う説得力のある理由は何でしょうか?これがないとできないんですね。
 
hoz:
ひとつだけわからないことがあるんです。新オペレーターの 使用を強制する正当な理由は何でしょうか?なくても大丈夫ですか?


オブジェクトを 動的に作成 したい場合に必要です。どのような種類のオブジェクトが何個必要なのか、事前に分からない場合。

 
hoz:
Так я вот одного не пойму. Какие веские причины принуждают к использованию оператора new ? Без него типа никак?
Integer:
オブジェクトを動的に作成する必要がある場合に必要です。必要なオブジェクトの数や種類が事前に分からない場合は、

動的な クラス配列を 使用することができます。MQLではこれが通用します。C++では、クラスのメンバの初期化に問題がある場合があります。だから、配列の中にスマートポインタを入れた方がいいんです。そのため、クラスの初期化やメモリのクリアなどの処理が不要になります。

 
mql5:
class cFather
 {
 public:
 int GetData() {return 3;}
 };
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 class cChild : public cFather
 {
 public:
 int GetData() {return 5;}
 };

 int f(cFather *p) {return p.GetData();}
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 int OnStart()
 {
 cChild obj,*ptr=GetPointer(obj);
 f(ptr); // вернет 3
 ((cFather *)ptr).GetData(); // вернет 3

 return 0;
 }

この構造は、どのように「読む」のでしょうか?

((cFather *)ptr).GetData();

あ、特に。

(cFather *)ptr)
見ていて要領を得ない...。
 
hoz:

この構造は、どのように「読む」のでしょうか?

((cFather *)ptr).GetData();

ptr がcFather 型(クラス)に変換され、その(cFather)メソッド GetData()呼び出さ れる。

ってな具合に

 
keekkenen:

ptr がcFather 型(クラス)に変換され、その(cFather)メソッド GetData()呼び出さ れる。

ってな具合に

変な話だなあ...。おおよそそう思っていましたが...タイプ(クラス)にキャストするのは無理がありますね。とにかくプログラミングでは、私が聞いた限りでは、型(クラス)にキャストすることは推奨されません。しかし、標準的な型変換ではなく、むしろクラス変換なのです。

さて、今一度このコードに立ち返ってみましょう。

class cFather
 {
 public:
 int GetData() {return 3;}
 };
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 class cChild : public cFather
 {
 public:
 int GetData() {return 5;}
 };

 int f(cFather *p) {return p.GetData();}
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 int OnStart()
 {
 cChild obj,*ptr=GetPointer(obj);
 f(ptr); // вернет 3
 ((cFather *)ptr).GetData(); // вернет 3

 return 0;
 }

ここで、f 関数プロトタイプの パラメータにおいて、f 関数がcFather クラスのメソッドをパラメータに取っていることが明確にわかる。さらに、STARTのコードでは次のような状況が見られます。

 f(ptr); // вернет 3

これは、f 関数がcFather クラスのメソッドではなく、cChild クラスへのポインタを取るところです。cChild obj なので、 *ptr = GetPointer( obj ) となります。

どういう理屈なんですか?

 

論理はどこに?

f()メソッドの中で、入力されたパラメータは、cFather(またはその子孫)に対して正しく処理される、というロジックだと思います。

 
keekkenen:

論理はどこに?

f() メソッドでは、入力されたパラメータはcFather (またはその後継者) で正しく処理される、というロジックになっていると思います。

すなわち

 int f(cFather *p) {return p.GetData();}

ここで*pcFather へのポインタである ?

同時に、C++を勉強しているので、似たような語彙に少し戸惑っています。ポインターはここが違うんですけどね

 
hoz:

すなわち

ここで*pcFather へのポインタである ?

同時に、C++を勉強しているのですが、似たような語彙に少し戸惑います。ここでの指摘は、同じではありませんが

cFatherは ポインタ型です。ポインタ変数自体がクラスのインスタンスを指している。
 

2週間ぶりの質問です。聞いてみることにした。あまり複雑なことではないのですが、論理的に考えて、このような選択肢もあるのかなと思います。以下はそのコードです。

struct Name
  {
   string            first_name;                 // имя
   string            last_name;                  // фамилия
  };
class CPerson
  {
protected:
   Name              m_name;                     // имя
public:
   void              SetName(string n);
   string            GetName(){return(m_name.first_name+" "+m_name.last_name);}
private:
   string            GetFirstName(string full_name);
   string            GetLastName(string full_name);
  };
void CPerson::SetName(string n)
  {
   m_name.first_name=GetFirstName(n);
   m_name.last_name=GetLastName(n);
  }
string CPerson::GetFirstName(string full_name)
  {
   int pos=StringFind(full_name," ");
   if(pos>0) StringSetCharacter(full_name,pos,0);
   return(full_name);
  }
string CPerson::GetLastName(string full_name)
  {
   string ret_string;
   int pos=StringFind(full_name," ");
   if(pos>0) ret_string=StringSubstr(full_name,pos+1);
   else      ret_string=full_name;
   return(ret_string);
  }

このコードには、2つのパブリック関数しかありません。

public:
   void              SetName(string n);
   string            GetName(){return(m_name.first_name+" "+m_name.last_name);}

そして、2つのプライベート関数は、必要な瞬間にパブリック関数を介して、いや、パブリック関数を直接呼び出す。面白いのは、void SetName(string n) 関数にはパラメータnが ありますが、プライベートメソッドprivate:string GetFirstName(string full_name)string GetLastName(string full_name) には、なぜか同じパラメータがない点です。しかし、このコードそのものを例にとると(他のコードではなく)、プライベートメソッドはパブリックメソッドを介して同じパラメータで呼び出され、それ以外の方法はありません。では、なぜパラメータに異なる名前を付ける必要があるのでしょうか?

質問が明確であることを望みます。