オブジェクト

  1. 等価比較では、rhsが非nullであり、メンバーが等しいことで十分である。
    enum Color { blue, green, red }
    
    class Point {
        int x;
        int y;
        Color color;
    
    // ...
    
        override bool opEquals(Object o) const {
            const rhs = cast(const Point)o;
    
            return rhs && (x == rhs.x) && (y == rhs.y);
        }
    }
    D
  2. 右側のオブジェクトの型もPointの場合、まずxメンバーの値が比較され、次にyメンバーの値が比較される。
    class Point {
        int x;
        int y;
        Color color;
    
    // ...
    
        override int opCmp(Object o) const {
            const rhs = cast(const Point)o;
            enforce(rhs);
    
            return (x != rhs.x
                    ? x - rhs.x
                    : y - rhs.y);
        }
    }
    D
  3. 以下のopCmp内で、const TriangularArea型にキャストすることはできないことに注意。rhsconst TriangularAreaの場合、そのメンバーrhs.pointsconstになる。opCmpのパラメータはconstではないため、rhs.points[i]point.opCmpに渡すことはできない。
    class TriangularArea {
        Point[3] points;
    
        this(Point one, Point two, Point three) {
            points = [ one, two, three ];
        }
    
        override bool opEquals(Object o) const {
            const rhs = cast(const TriangularArea)o;
            return rhs && (points == rhs.points);
        }
    
        override int opCmp(Object o) const {
            auto rhs = cast(TriangularArea)o;
            enforce(rhs);
    
            foreach (i, point; points) {
                immutable comparison = point.opCmp(rhs.points[i]);
    
                if (comparison != 0) {
                    /* ソート順はすでに決定されている。
                     * 結果を返すだけだ。 */
                    return comparison;
                }
            }
    
            /* これらのオブジェクトは、すべての点が等しいことから、
             * 等しいものとみなされる。 */
            return 0;
        }
    
        override size_t toHash() const {
            /* 'points'メンバーは配列なので、
             * 配列型用の既存の
             * toHashアルゴリズムを利用できる。 */
            return typeid(points).getHash(&points);
        }
    }
    D