0

xとyを引数として取るこのクラス「Point」があります。ただし、それらをランダムな値に初期化するコンストラクターを作成する必要があります。それがどのように行われるのか正確にはわかりません。これが私のコードです: コンストラクターを作成しましたが、x と y を設定しても不合理な値を取得しています。

#include <iostream>
#include <cmath>
#include <ctime>

    using namespace std;
    class Point
    {
    private:
        double x;
        double y;

    public:

        double get_x()
        {
            return x;
        }
        void set_x (double x)
        {
            this->x = x;
        }
        double get_y()
        {
            return y;
        }
        void set_y(double y)
        {
            this->y = y;
        }
        double distanceTo(Point p)
        {
            double x2 = p.get_x();
            double y2 = p.get_y();
            return sqrt( pow(x-x2,2) + pow(y-y2,2) );
        }
        Point(double x, double y)
        {
            x = rand()*1.0 / RAND_MAX  * 100;
            y = rand()*1.0 / RAND_MAX  * 100;
        }
        Point(){};


    };

    void main()
    {
        Point a(1.2,0.5);
        Point b;
        b.set_x(1);
        b.set_y(1);
        cout << a.distanceTo(b);
        system ("Pause");
    }
4

6 に答える 6

4

これは、メンバー変数を初期化するのではなく、コンストラクターに渡される変数のコピーを変更するためです。xしたがって、およびy(クラスバージョン)が初期化されないため、ガベージ値が表示されます。これを次のように変更する必要があります。

Point()
{
    x = rand()*1.0 / RAND_MAX  * 100;
    y = rand()*1.0 / RAND_MAX  * 100;
}

さらに、どこでも呼び出すことはありませんsrand()- ランダムジェネレーターを適切にシードするために、ある時点でこれを行う必要があります。

于 2013-04-24T14:00:07.210 に答える
0

デフォルトのコンストラクターは何もしません。値を初期化することさえしません。つまり、未指定の値を持つことになります。

2 つの引数を取るコンストラクターは、その名前がメンバーの名前を隠しているため、引数に代入するだけです。

于 2013-04-24T14:01:50.887 に答える
0

「名前の衝突」が発生しています。この関数では

    Point(double x, double y)
    {
        x = rand()*1.0 / RAND_MAX  * 100;
        y = rand()*1.0 / RAND_MAX  * 100;
    }

コンパイラは、割り当て時にどの x を意味するかを認識していません。言語規則では、入力引数を割り当てる必要があると書かれていますが、これに頼るべきではありません。不必要に紛らわしいからです。

メンバー変数の命名規則を採用することをお勧めします。一般的な 2 つの方法は、メンバーの前に "m" または "_" を付けることです。個人的には「ム」が好きです。

次に、コードは次のようになります。

class Point
{
   public:
      double mX;
      double mY;

   Point(double x, double y)
    {
        mX = rand()*1.0 / RAND_MAX  * 100;
        mY = rand()*1.0 / RAND_MAX  * 100;
    }
}

また、この場合のコンストラクター引数は冗長であるため、削除できます。

上記の他の回答のいくつかも正しいですが、単純な関数でスコープ名( Point:: など)を明示する必要がある場合は、クラス設計が悪いことを示しています。

于 2013-04-24T14:05:19.160 に答える
0

変化する

Point(){};

Point()
{
    x = rand()*1.0 / RAND_MAX  * 100;
    y = rand()*1.0 / RAND_MAX  * 100;
}

また、間違いを避けるために引数\メンバー名を変更することをお勧めします。私は個人的m_にメンバーに使用するのが好きです:

private:
    double m_x;
    double m_y; 
于 2013-04-24T14:02:44.080 に答える
0

コンストラクターで一時変数を変更しているためです (同じスコープでの名前の衝突)。試す:

Point(double x, double y)
{
  Point::x = rand()*1.0 / RAND_MAX  * 100;
  Point::y = rand()*1.0 / RAND_MAX  * 100;
}

しかし、それはコンストラクターに与えられた引数を完全に無視します。しかし、変数のさまざまなスコープを区別する方法がわかったので、ここから先に進むことができると思います。

于 2013-04-24T13:59:39.943 に答える