0

次のコードのように、二次クラスの 2 つのインスタンスを加算できるように、オーバーロードされた operator+ 関数を記述します。

quadratic y1 = quadratic (1.0, -5.0, 7.0);
quadratic y2 = quadratic (-3.0, -2.0, 10.0);
quadratic y3;
double result;

y3 = y1 + y2;
result = y1.evaluate (10.0);
cout << result <<endl;

参考までに、2 つの数値関数の実装を次に示します。

double quadratic:: evaluate (const double x) {
return ((a * x * x) + (b * x) + c);
}

void quadratic::getCoefficients (double &A, double &B,
double &C) {
A = a; B = b; C = c;
}

教祖の助けを必死に求める!どんな助けでも大歓迎です!

4

3 に答える 3

0

単純なアプローチは、少し希望的観測を使用することです。加算演算を作成する前に、2つのオブジェクトがあると考えてください。

実際、何が起こっているのかというと、操作を定義するときに、後で適用されるアルゴリズムを作成しているということです。呼び出しの場所で、一部のユーザーがタイプする場合a+baおよびbは、追加するタイプの有効なインスタンスである必要があります。操作を定義する際、関数またはメソッドへの引数は、後で存在する有効なインスタンスへの引数を表します。

これは宿題なので、別の例に従います。と座標vector2dを表す2つのdoubleを含むクラスを作成することを検討してください。xy

class vector2d {
public:
   //...
private:
   double x,y;
};

そして、オブジェクトに適用できるいくつかの操作を提供したいとしvector2dます。operator+=同じベクトルに2番目のベクトルを追加した結果をベクトルに格納する方法として次のように定義できます。

class vector2d {
public:
   //...
   vector2d& operator+=( const vector2d& rhs )
   {
      x += rhs.x;
      y += rhs.y;
      return *this;
   }
};

vector2d慣例として、 fromへの参照を返しoperator+=ます。操作を呼び出すオブジェクト(これはメンバー関数、*thisオブジェクト)と、パラメーターとして受け取る2番目のオブジェクトの両方を操作します。この時点では、プログラムに作成された単一のオブジェクトはなく、オペランドではなく操作を定義しているだけであることに注意してください。右側の引数rhsは、定数参照を介して処理されます(変更しないことを約束するオブジェクトへの参照を取得します)。実際の操作は単純で、各座標を個別に追加します。規則では変更されたオブジェクトへの参照が返されるため、を返し*thisます。

2つのオブジェクトに関して操作の実行方法を定義しました。これで、次のように使用できます。

int main() {
   vector2d a( 5, 10 );    // assume that there is a constructor that 
                           // takes 2 doubles in the ellipsis above...
   vector2d b( 2.5, 7.5 );
   a += b;
}

ここで、電話をかけることができるようにするには、ユーザーは2つのオブジェクトを持っている必要があります。オブジェクトのインスタンスを実際に必要としない操作を定義するために、パラメーターを使用してそれを抽象化します。しかし、実際に操作を使用するには、操作するオブジェクトが必要です。この時点で、それらは実際に作成され、名前が付けられaますb。次に、ユーザーは操作を呼び出しますa += b。呼び出しがコンパイラによってあまり美しくないものに変換されるのはメンバーメソッドであるため、つまり、引数として渡されるオブジェクトa.operator+=(b)のメンバーメソッドを呼び出します。operator+=ab

適切な加算演算を提供するために、free関数を書くことができます。この追加は2つの引数のいずれにも適用されませんが、3番目の引数を作成するため、メンバーメソッドではないことは理にかなっています。

vector2d operator+( vector2d lhs, const vector2d & rhs )
{
   lhs += rhs;
   return lhs;
}

この実装は慣用的です(一般的なパターン)。実装したら、前の観点からoperatorX=実装できます。operatorXここで注意が必要です。最初の引数を値で取得します。このように、コンパイラはlhsこの関数内でコピーを作成します。これは加算の最初の引数ではなく、そのコピーです。次に、既存の操作を使用してそのローカルコピーを変更し、結果をユーザーに返します。戻りオブジェクトも値によるものです。

使用法は似ています:

int main() {
   vector2d a( 5, 10 );
   vector2d b( 2.5, 7.5 );
   vector2d c = a + b;
}

呼び出しの場所では、無料の関数であるため、a+bに変換されます。operator+( a, b )次に、最初の引数が値によって渡されるため、関数の場合と同様にのコピーaが作成されて使用されlhsます。2番目の引数は参照によって渡され、変更しないことを約束します(したがってconst)。操作の結果はに保存されcます。

于 2010-09-14T08:16:57.333 に答える
0

だから....あなたはこの関数を宣言したいですか?

quadratic operator+(const quadratic& LHS, const quadratic& RHS);

として実装しますか?

quadratic operator+(const quadratic& LHS, const quadratic& RHS)
{
    double LHSCoefficients[3];
    LHS.getCoefficients(LHSCoefficients[0], LHSCoefficients[1], LHSCoefficients[2]);
    double RHSCoefficients[3];
    RHS.getCoefficients(RHSCoefficients[0], RHSCoefficients[1], RHSCoefficients[2]);
    return quadratic(LHSCoefficients[0] + RHSCoefficients[0], LHSCoefficients[1] + RHSCoefficients[1], LHSCoefficients[2] + RHSCoefficients[2]);
}

十分に単純であり、メソッド、静的メソッド、またはフレンド関数である必要はありません。気をquadratic::getCoefficientsつけてください。quadratic::evaluate実際には、呼び出し元のオブジェクトを常に保護する必要があります。inline const double& quadratic::getA() constまた、個々のコンポーネントのようなメソッドがある場合もあります。これにより、メモリと処理のオーバーヘッドが少なくなり、参照によって返されますが、コンポーネントを変更できなくなります。

于 2010-09-14T08:46:23.270 に答える
0

提供された関数から、quadratic には (少なくとも) 3 つのメンバー変数 a、b、および c があることが明らかです。

class quadratic
{
public:
//...
private:
  double a, b, c;
};

さらに、quadratic には 3 つの double と operator+ を取るコンストラクターがあると推測できます。

class quadratic
{
public:
  quadratic(double A, double B, double C) {/*...*/}
  quadratic operator+(const quadratic &other) {/*...*/}
  //...
private:
  double a, b, c;
};

残りの実装のどの部分に問題がありますか?

于 2010-09-14T00:21:52.957 に答える