スポンサーリンク
コメントに質問があったので使用例を置いておきたい。
HashSetは等価であることを比較するためにEqualsメソッドを持っていなければならない。
全てのクラスはObjectの子クラスなので、Equalsをオーバーライドしてもいいが、IEquatableを継承するとObject型ではなく指定した型のデータをとるEqualsをオーバーライドできるようになる。
#include "pch.h"
// 自作クラス // IEquatableを継承しているのでEqualsメソッドをオーバーライドすることで // インスタンスの等価判定が可能 public ref class DataType : System::IEquatable<DataType^> { private: int a, b; public: DataType() : a(0), b(0) {} DataType(int _a, int _b) : a(_a), b(_b) {} int geta() { return a; } int getb() { return b; } void set(int _a, int _b) { a = _a; b = _b; } /* // IEquatableを使用しない場合はObject^型で受け取って評価できる // ObjectのEqualsメソッドをオーバーライド virtual bool Equals(Object^ obj) override { if (obj == nullptr) return false; DataType^ other = dynamic_cast<DataType^>(obj); if (other == nullptr) return false; return a == other->a && b == other->b; } */ // IEquatableのEqualsメソッドを実装 virtual bool Equals(DataType^ other) { if (other == nullptr) return false; return (a == other->a) && (b == other->b); } // ObjectのGetHashCodeメソッドをオーバーライド virtual int GetHashCode() override { return a.GetHashCode() ^ b.GetHashCode(); } };
// 比較用クラス // IComparerを継承してCompareメソッドをオーバーライドする。 // このクラスをArray::Sortの第二引数に渡すことで、ソートの基準を変更できる。 public ref class Ccmp : System::Collections::Generic::IComparer<DataType^> { public: virtual int Compare(DataType^ x, DataType^ y) { if (x->geta() < y->geta()) return -1; if (x->geta() > y->geta()) return 1; if (x->getb() < y->getb()) return -1; if (x->getb() > y->getb()) return 1; } };
void sort_test() { array<DataType^>^ ary = gcnew array<DataType^>(3); ary[0] = gcnew DataType(1, 2); ary[1] = gcnew DataType(6, 8); ary[2] = gcnew DataType(2, 4); //ソート実行。 Ccmp^ cmp = gcnew Ccmp();//比較用クラスのインスタンスを作成し、 System::Array::Sort(ary, cmp);//Array::Sortの第二引数にそのハンドルを渡す for each (DataType^ data in ary) { System::Console::WriteLine("a = {0}, b = {1}", data->geta(), data->getb()); } }
void hashset_test() { using namespace System::Collections::Generic; // HashSetを使えるようにする // DataTypeのHashSetを作成 HashSet<DataType^>^ hashSet = gcnew HashSet<DataType^>(); // DataTypeのインスタンスを作成してHashSetに追加 DataType^ data1 = gcnew DataType(-1, 3); // 重複するデータ DataType^ data2 = gcnew DataType(4, 2); DataType^ data3 = gcnew DataType(-1, 3); // 重複するデータ hashSet->Add(data1); hashSet->Add(data2); hashSet->Add(data3); //hashSet内の全データ表示 for each (DataType ^ data in hashSet) { System::Console::WriteLine("a = {0}, b = {1}", data->geta(), data->getb()); } }
int main(array<System::String^>^ args) { sort_test(); hashset_test(); return 0; }
1 件のコメント
どうもありがとうございました。
hashset.add()で追加する要素のクラスには、ソートの様に「比較用クラス」を指定する必要は無いのですね。
public ref class DataType : System::IEquatable {}という定義方法が使えるというのは良い学習になりました。
こちらでも動作確認を行い、やりたいことが実現できるようになってきました。