かってきままに!

わたくし、とんちゃんが日々の話題をかってきままに記していきます。

Array.Sort(), List.Sort() + Icomparable実装

2010-09-30 13:46:17 | C++/CLI

#using <mscorlib.dll>

enum class SortCategory {
 Number, Name
};

ref class test : System::IComparable
//ref class test : System::IComparable <test^>    //型を指定するとき
{
public:
 static SortCategory SortCat;            //ソートを行う
 static bool SortReverse;                //ソートの方向
 int value;
 System::String^ str;

 test(int n, System::String^ s) {        //コンストラクタ
  value = n;
  str = s;
 }

 virtual int CompareTo(Object^ obj) {    //Icomparable の実装

 //virtual int CompareTo(test^ obj) {    //型を指定したとき
 //型を指定した場合は safe_cast 無しで obj を test^ として使えます
 //クラスの宣言で Icomparable <test^> とする必要があります


  if(!SortReverse){        //昇順のとき

   if(SortCat == SortCategory::Name){            //名前でソート
    return this->str->CompareTo(safe_cast<test^>(obj)->str);

   }else if(SortCat == SortCategory::Number){    //番号でソート
    return this->value.CompareTo(safe_cast<test^>(obj)->value);

   }

  }else{                    //降順のとき

   if(SortCat == SortCategory::Name){            //名前でソート
    return safe_cast<test^>(obj)->str->CompareTo(this->str);

   }else if(SortCat == SortCategory::Number){    //番号でソート
    return safe_cast<test^>(obj)->value.CompareTo(this->value);

   }
  }
  throw gcnew System::Exception("エラー");
 }
};

int main(array<System::String^>^ argc)
{
 //参照クラス test の array をつくり適当にデータを与える
 array<test^>^ te = gcnew array<test^>(5);
 te[0] = gcnew test(4, "apple");
 te[1] = gcnew test(2, "pare");
 te[2] = gcnew test(5, "grape");
 te[3] = gcnew test(3, "banana");
 te[4] = gcnew test(1, "pineapple");

 //現在の内容を表示
 System::Console::WriteLine("array");
 for each(test^ t in te)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 //番号、昇順
 test::SortReverse = false;
 test::SortCat = SortCategory::Number;

 System::Array::Sort(te);

 for each(test^ t in te)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();
 
 //番号、降順
 test::SortReverse = true;
 test::SortCat = SortCategory::Number;

 System::Array::Sort(te);

 for each(test^ t in te)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 //名前、昇順
 test::SortReverse = false;
 test::SortCat = SortCategory::Name;

 System::Array::Sort(te);

 for each(test^ t in te)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 //名前、降順
 test::SortReverse = true;
 test::SortCat = SortCategory::Name;

 System::Array::Sort(te);

 for each(test^ t in te)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 
 //参照クラス test の list をつくり適当にデータを与える
 System::Collections::Generic::List<test^>^ li = gcnew System::Collections::Generic::List<test^>();
 li->Add(gcnew test(21, "blue"));
 li->Add(gcnew test(18, "red"));
 li->Add(gcnew test(28, "violet"));
 li->Add(gcnew test(11, "green"));
 li->Add(gcnew test(30, "silver"));

 //現在の内容を表示
 System::Console::WriteLine("list");
 for each(test^ t in li)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 //番号、昇順
 test::SortReverse = false;
 test::SortCat = SortCategory::Number;

 li->Sort();

 for each(test^ t in li)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();
 
 //番号、降順
 test::SortReverse = true;
 test::SortCat = SortCategory::Number;

 li->Sort();

 for each(test^ t in li)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 //名前、昇順
 test::SortReverse = false;
 test::SortCat = SortCategory::Name;

 li->Sort();

 for each(test^ t in li)
  System::Console::WriteLine(t->value + ", " + t->str);

 System::Console::WriteLine();

 //名前、降順
 test::SortReverse = true;
 test::SortCat = SortCategory::Name;

 li->Sort();

 for each(test^ t in li)
  System::Console::WriteLine(t->value + ", " + t->str);
 System::Console::WriteLine();

 return 0;
}

/*
表示結果
array
4, apple
2, pare
5, grape
3, banana
1, pineapple

1, pineapple
2, pare
3, banana
4, apple
5, grape

5, grape
4, apple
3, banana
2, pare
1, pineapple

4, apple
3, banana
5, grape
2, pare
1, pineapple

1, pineapple
2, pare
5, grape
3, banana
4, apple

list
21, blue
18, red
28, violet
11, green
30, silver

11, green
18, red
21, blue
28, violet
30, silver

30, silver
28, violet
21, blue
18, red
11, green

21, blue
11, green
18, red
30, silver
28, violet

28, violet
30, silver
18, red
11, green
21, blue
*/


array

2010-09-24 17:26:30 | C++/CLI

#include <iostream>
#using <mscorlib.dll>


ref class A {

public:

 int field;
};


int main(array<System::String ^> ^args)
{

 array<int>^ objectI = gcnew array<int>(5);

 //array は配列の情報を持つオブジェクトのハンドル
 //c の配列の様に配列の先頭を示す物ではない
 //int は自動的に 0 で初期化される


 array<A^>^ objectA = gcnew array<A^>(5);

 //配列が参照クラスの時は、ハンドルを配列にもつ
 //この時点では配列の中身は nullptr なので中身も初期化する


 for each(A^% obj in objectA)
  obj = gcnew A();

 //配列の数分 gcnew で確保する
 //for each 内で A^% としないと objectA は初期化できない
 
 //A^ obj だと
 //1.  ローカル変数 obj に objectA 内の 配列の要素 A^ がコピーされる
 //2.  obj に gcnew で新しいハンドルが入る
 //3.  obj は objectA 内の配列の要素 A^ とは別の変数なので objectA の要素は初期化されない

 //A^% obj だと
 //1.  トラッキング参照 obj が objectA 内の 配列の要素 A^ のエイリアスとなる
 //2.  obj に gcnew で新しいハンドルが入る
 //3.  obj は objectA 内の配列の要素 A^ その物なので objectA の要素は初期化される


 for each(int% n in objectI)
  n++;

 //とにかく配列そのものに手を加えたい場合は参照をつかう

 
 getchar();
  
 return 0;

}


ref class

2010-09-21 16:38:39 | C++/CLI

#include <iostream>
#using <mscorlib.dll>

ref class A {         //参照クラス ref をつけます。

public:

 int a;

};

int main(array<System::String^>^ args)
{
 A^ a = gcnew A();    //参照クラスはマネージヒープ上に作られる。返されるのはハンドルという。
                      //インスタンスはGCによってマネージヒープ上を移動する。
                      //ポインタのように演算はできない。
                      //gcnewで作成してdeleteのような後始末は勝手にやってくれるので必要ない。
                      //ただし、いつ削除されるかはわからない。

 a->a = 10;           //アクセスにはアロー演算子を使う。


 A b;                 //このようにも使える。
                      //内部的には A^ b = gcnew A となっている。
                      //この場合スコープを抜けると削除される。

 b.a = 20;            //この場合はドット演算子を使う。

 
 System::Console::WriteLine(a->a);
 System::Console::WriteLine(b.a);

 getchar();

 return 0;
}

// 表示結果
// 10
// 20