メンバオブジェクトを定義する

C++/CLI の LCM Class で、メンバオブジェクト(GCM)を定義します。

前田稔の超初心者のプログラム入門

プログラムの説明

  1. メンバオブジェクトとは Object Class のメンバとして Object Class を定義することです。
    簡単な例として、LCM Class のメンバとして GCM Class を定義してみましょう。
    class  LCM
    {
      private:
        int     val;
    
      public:
        GCM     Gcmcls;         //メンバオブジェクト
    
  2. メンバオブジェクトになる GCM Object Class です。
    Constructor と Destructor が実行されるタイミングを調べるためにメッセージを表示してみました。
    /*★ LCM Class で、メンバオブジェクト(GCM)を定義    前田 稔 ★*/
    #include <iostream>
    using namespace std;
    
    class  GCM
    {
      private:
        int     wk,val;
    
      public:
        GCM(int v1, int v2)
        {   cout << "GCM Constructor の開始\n";
            wk= v1;
            val= v2;
            while(wk!=val)
            {   if (wk>val) wk-= val;
                else        val-= wk;
            }
        }
        ~GCM()
        {   cout << "GCM Destructor の開始\n";
        }
        int GetGcm()
        {
            return val;
        }
    };
    
  3. GCM Object Class をメンバに持つ LCM Object Class です。
    こちらも Constructor と Destructor でメッセージを表示しています。
    メンバオブジェクトの定義です。
    本来ならばこのように書くと Object Class が直接生成されると説明しましたね。
    所がメンバオブジェクトの場合は事情が違います。
    GCM Gcmcls; //メンバオブジェクト
    ここはクラスの型(Prototype)を宣言する場所なので、次のような書き方は出来ません。
    GCM Gcmcls(24,32); //エラーになる
    GCM のコンストラクタは LCM のコンストラクタに「:」を付けて呼び出します。
    LCM(int v1, int v2) : Gcmcls(v1, v2)
    LCM を計算するために GCM Class の GetGcm() 関数を呼び出します。
    val= v1*v2/Gcmcls.GetGcm();
    class  LCM
    {
      private:
        int     val;
    
      public:
        GCM     Gcmcls;         //メンバオブジェクト
        LCM(int v1, int v2) : Gcmcls(v1, v2)
        {   cout << "LCM Constructor の開始\n";
            val= v1*v2/Gcmcls.GetGcm();
        }
        ~LCM()
        {   cout << "LCM Destructor の開始\n";
        }
        int GetLcm()
        {
            return val;
        }
    };
    
  4. LCM Object Class をグローバル領域で定義しています。
    main() 関数では、LCM Object Class の Gcmcls を通じて GetGcm() 関数を呼び出します。
    LCM     Lcmcls(24,32);
    
    int main()
    {
        cout << "main() の開始\n";
        cout << "GCM(24,32) は " << Lcmcls.Gcmcls.GetGcm() <<
             " で、 LCM(24,32) は " << Lcmcls.GetLcm() << " です\n";
        cout << "main() の終了\n";
        return 0;
    }
    
  5. このプログラムの実行結果です。
    GCM Constructor が実行されてから LCM Constructor が実行されます。
    GCM Constructor の開始
    LCM Constructor の開始
    main() の開始
    GCM(24,32) は 8 で、 LCM(24,32) は 96 です
    main() の終了
    LCM Destructor の開始
    GCM Destructor の開始
    
  6. 今説明したような「メンバオブジェクトを定義する」方法は余りお勧め出来ません。
    このようなケースでは、この後のページで説明する「オブジェクトを継承する」が一般的で良く使われます。

new で Object を生成する

  1. 最近では Object Class を new で生成(作成)する方法が一般的になっています。
    JAVA や C# では、言語仕様からポインタが廃止(使用が制限)されて、先に説明したような方法は使えなくなっています。
  2. LCM Class に含まれる GCM Class を、ポインタで定義してみました。
    new で生成して delete で開放されるので、プログラムの制御の流れが明快で、こちらの方がお勧めです。
    class  LCM
    {
      private:
        int     val;
    
      public:
        GCM     *Gcmcls;        //メンバオブジェクト
        LCM(int v1, int v2)
        {   cout << "LCM Constructor の開始\n";
            Gcmcls = new GCM(v1,v2);
            val= v1*v2/Gcmcls->GetGcm();
        }
        ~LCM()
        {   cout << "LCM Destructor の開始\n";
            delete Gcmcls;
        }
    
        int GetLcm()
        {
            return val;
        }
    };
    
    LCM     *Lcmcls;
    
    int main()
    {
        cout << "main() の開始\n";
        Lcmcls = new  LCM(24,32);
        cout << "GCM(24,32) は " << Lcmcls->Gcmcls->GetGcm() <<
             " で、 LCM(24,32) は " << Lcmcls->GetLcm() << " です\n";
        delete Lcmcls;
        cout << "main() の終了\n";
        return 0;
    }
    

超初心者のプログラム入門(C/C++)