ref class と value class

C++/CLI の normal class と ref class と value class の説明です。

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

normal class, ref class, value class

  1. Maneged Mode で一般的に使われる Object Class は ref class です。
    ここでは normal class と ref class と value class を使ってプログラムしてみます。
  2. 先に余りなじみの無い value class に付いて説明しましょう。 (^_^;)
    値(value)クラスは値型オブジェクトにアクセスするのに遠回しなメモリ要求することなく「効果的に早くデータのコピー」が出来るように設計されています。
    その結果として、データ表現に値クラスを使うことはガベージ・コレクタの負担を減らし、リソース管理を無用にします。
    全ての値クラスは暗黙のうちにパラメータのないインスタンス・コンストラクタを持っており、それは全ての値型フィールドにそのデフォルト値を、 そして、全てのハンドル型フィールドに nullptr を設定した結果を値として返します。
  3. normal class は、従来から使われているC++言語の Object Class の書き方です。
  4. ref class は、従来から使われている Object Class を Maneged Mode に合わせた書き方と言ったら良いのでしょうか。 (^_^;)
  5. 処理の内容を理解し易いように、struct(class として定義されている)を例に取ってプログラムします。
    struct と class に本質的な違いはありません。詳細は「UnManeged Mode(Win32 Code) の構造体」を参照して下さい。

プログラムの説明

  1. Normal class のプログラムです。
    関数 func() にパラメータとして、構造体のポインタを「&data」で渡します。
    Maneged Mode のように「%data」で渡すことは出来ません。
    func では、構造体のポインタを「DATA* pData」で受け取って sum の値を計算します。
    Maneged Mode のように「DATA^ pData」で受け取ることは出来ません。
    関数 func() から戻ってから sum の値(10+20=30)を表示します。
    /*★ Normal struct  %data は使えない  前田 稔 ★*/
    using namespace System;
    
    class   DATA
    {
      public:
        int     v1;
        int     v2;
        int     sum;
    };
    
    //void func(DATA^ pData)
    void func(DATA* pData)
    {
        pData->sum = pData->v1+pData->v2;
    }
    
    int main()
    {
        DATA    data;
    
        data.v1 = 10;
        data.v2 = 20;
    //    func(%data);
        func(&data);
        Console::WriteLine("10 + 20 = {0} です",data.sum);
        System::Console::ReadLine();
        return 0;
    }
    
  2. ref class のプログラムです。
    関数 func() のパラメータとして、構造体のポインタを「%data」で渡します。
    関数 func() では、構造体のポインタを「DATA^ pData」で受け取ります。
    Normal Class のプログラムと比べてみて下さい。
    関数 func() から戻ってから sum の値(10+20=30)を表示します。
    /*★ ref struct    前田 稔 ★*/
    using namespace System;
    
    ref  class   DATA
    {
      public:
        int     v1;
        int     v2;
        int     sum;
    };
    
    void func(DATA^ pData)
    {
        pData->sum = pData->v1+pData->v2;
    }
    
    int main()
    {
        DATA    data;
    
        data.v1 = 10;
        data.v2 = 20;
        func(%data);
        Console::WriteLine("10 + 20 = {0} です",data.sum);
        System::Console::ReadLine();
        return 0;
    }
    
  3. value class のプログラムです。
    ref class と違うところは「ref class DATA」が「value class DATA」に変わっただけです。
    所が、このプログラムでは sum の値が計算されていません。
    value class では func() に渡される「%data」は、構造体(Class)のコピーのようです。
    normal class や ref class のプログラムと比べてみて下さい。
    /*★ value struct  sum は設定されない  前田 稔 ★*/
    using namespace System;
    
    value  class   DATA
    {
      public:
        int     v1;
        int     v2;
        int     sum;
    };
    
    void func(DATA^ pData)
    {
        pData->sum = pData->v1+pData->v2;
    }
    
    int main()
    {
        DATA    data;
    
        data.v1 = 10;
        data.v2 = 20;
        func(%data);
        Console::WriteLine("10 + 20 = {0} です",data.sum);
        System::Console::ReadLine();
        return 0;
    }
    

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