-2

私は自分のコードを投稿する方法を間違えました。それはちょっと怠惰で、私のためにすべてをやりたいだけです。以下のコードでの演算子のオーバーロードと、このコードがメインプログラムで何をしているのかを学びたいです。

static public explicit operator Int32(Vector v)
        {
            return v.Length;
        }

        public override string ToString()
        {
            String res = "<";
            for (int i = 0; i < elements.Length; i++)
                res += " " + elements[i];
            res += " >";
            return res;
        }

        public override bool Equals(Object v)
        {
            return (this == (Vector)v);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

このコードは、ベクトルの加算、減算、乗算、および等式/不等式の演算子をオーバーライドすることにより、ベクトルのクラスを実装します。1つのオペランド(実数または整数)の演算を考慮に入れてください。操作で次元ベクトルが一致する場合は、例外をスローします。

namespace ConsoleApplication3
{



    public class Vector
    {
        private Double[] elements;

        public Vector()
        {
            this.elements = null;
        }

        public Vector(Int32 size)
        {
            if (size < 0) throw new Exception("Invalid vetors size");        
            elements = new Double[size];
        }

        public Vector(params Double[] elements)
        {
            this.elements = elements;
        }

        public Vector(Vector v)
        {
            this.elements = v.elements;
        }

        public int Length
        {
            get
            {
                if (elements == null) return 0;
                return elements.Length;
            }
        }

        public Double this[int index]
        {
            get 
            {
                return elements[index];
            }
            set 
            {
                elements[index] = value;
            }
        }

        static public Vector operator+(Vector v1, Vector v2)
        {
            if (v1.Length != v2.Length)
                throw new Exception("size of vectors are different");
            Vector res = new Vector(v1.Length);
            for (int i = 0; i < res.Length; i++)
                res[i] = v1[i] + v2[i];
            return res;
        }

        static public Vector operator+(Vector v, Double d)
        {
            Vector res = new Vector(v.Length);
            for (int i = 0; i < v.Length; i++ )
                res[i] = v[i] + d;
            return res;
        }

        static public Vector operator +(Double d, Vector v)
        {
            return (v + d);
        }

        static public Vector operator -(Vector v, Double d)
        {
            Vector res = new Vector(v.Length);
            for (int i = 0; i < v.Length; i++)
                res[i] = v[i] - d;
            return res;
        }

        static public Vector operator -(Double d, Vector v)
        {
            Vector res = new Vector(v.Length);
            for (int i = 0; i < v.Length; i++)
                res[i] = d - v[i];
            return res;
        }

        static public Vector operator *(Vector v, Double d)
        {
            Vector res = new Vector(v.Length);
            for (int i = 0; i < v.Length; i++)
                res[i] = v[i] * d;
            return res;
        }

        static public Vector operator *(Double d, Vector v)
        {
            return (v * d);
        }

        static public Vector operator -(Vector v1, Vector v2)
        {
            if (v1.Length != v2.Length)
                throw new Exception("size of vectors are different");
            Vector res = new Vector(v1.Length);
            for (int i = 0; i < res.Length; i++)
                res[i] = v1[i] - v2[i];
            return res;
        }

        static public Vector operator *(Vector v1, Vector v2)
        {
            if (v1.Length != v2.Length)
                throw new Exception("size of vectors are different");
            Vector res = new Vector(v1.Length);
            for (int i = 0; i < res.Length; i++)
                res[i] = v1[i] * v2[i];
            return res;
        }

        static public Boolean operator ==(Vector v1, Vector v2)
        {
            if (v1.Length != v2.Length)
                return false;            
            for (int i = 0; i < v1.Length; i++)
                if(v1[i] != v2[i]) return false;
            return true;
        }

        static public Boolean operator !=(Vector v1, Vector v2)
        {
            return (!(v1 == v2));
        }

        static public explicit operator Int32(Vector v)
        {
            return v.Length;
        }

        public override string ToString()
        {
            String res = "<";
            for (int i = 0; i < elements.Length; i++)
                res += " " + elements[i];
            res += " >";
            return res;
        }

        public override bool Equals(Object v)
        {
            return (this == (Vector)v);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Vector v1 = new Vector(new Double[]{1, 2, 3, 4});
            Vector v2 = new Vector(2, 3, 4, 5);
            Console.WriteLine(v1 + " + " + v2 + " = " + (v1 + v2));
            Console.WriteLine(v1 + " - " + v2 + " = " + (v1 - v2));
            Console.WriteLine(v1 + " * " + v2 + " = " + (v1 * v2));
            Console.WriteLine(v1 + " * " + 7 + " = " + (v1 * 7));
            Console.ReadKey(true);
        }
    }
}
4

3 に答える 3

2

ちょっとしたコードレビュー、ここにいくつかの大きな赤い旗。

このコンストラクターは危険なほど間違っています。

    public Vector(Vector v)
    {
        this.elements = v.elements;
    }

elementsは(配列への)参照であるため、同じ要素を共有する2つのVectorオブジェクトをここで作成しています。

Vector v1 = new Vector(10);
Vector v2 = new Vector(v1);  // 2 vectors, 1 elements

v1[0] = 1.2;
Console.WriteLine(v2[0]);  // prints 1.2

そして、これは同じ理由で少なくとも危険です。

    public Vector(params Double[] elements)
    {
        this.elements = elements;
    }

これらの2つの(そしておそらくさらにいくつかの)問題の解決策は、このクラスを不変になるように再設計することです。手始めに、インデクサからセッターを削除します。

この演算子は非常に疑わしいです、あなたのユースケースは何ですか:

    static public explicit operator Int32(Vector v)
    {
        return v.Length;
    }

ベクトルはどういうわけか長さであり、実際に長さがあることを示唆しています。

于 2012-10-10T19:27:15.413 に答える
2

演算子のオーバーロードは非常に単純であり、提供されたコードに基づいて、あなたがそれを理解しているように見えます。ここで問題が発生する可能性があるのは、たとえば次のようなものです。

static public Vector operator *(Double d, Vector v)
    {
        return (v * d);
    }

*演算子を演算子自体で定義していますが、これは無意味であり、おそらく機能しません(DoubledにVectorvを掛けると機能する場合がありますが、すでに機能を使用しています)。

関数を理解している場合、演算子は2つのパラメーターを使用して同じことを行い、必要な値を返します。

于 2012-10-10T19:30:41.593 に答える
1

C#では、すべてのアイテムがオブジェクトであるため、すべてがオブジェクトクラスに含まれます。

http://msdn.microsoft.com/en-us/library/system.object.aspx

したがって、すべてのオブジェクトには、少なくともObjectから継承されたメソッドがあります。ToStringのようなこの関数のいずれかをオーバーライドすると、基本クラスで使用可能な関数の実装が実装に置き換えられます。

演算子の場合も同じ状況です。さらに、2つの配列(またはユーザーが定義した他の型)の演算子+は存在しないため、ユーザーからの実装が必要です。

演算子はメソッドと似ていますstaticpublicBoolean operator ==(Vector v1、Vector v2)

2つのベクトル項が必要であり、ブール値は次のものと同等です(構文上ではありません):Boolean Equal(Vector v1、Vector v2)

残りの部分についても同じアプローチ。

お役に立てば幸いです。

于 2012-10-10T19:38:22.720 に答える