2010-04-14 68 views
3

我有以下的多項式類我的工作:爲什麼我的運營商超載工作不正常?

#include <iostream> 

using namespace std; 

class Polynomial 
{ 
//define private member functions 
private: 
    int coef[100]; // array of coefficients 
    // coef[0] would hold all coefficients of x^0 
    // coef[1] would hold all x^1 
    // coef[n] = x^n ... 

    int deg;  // degree of polynomial (0 for the zero polynomial) 

//define public member functions 
public: 
    Polynomial::Polynomial() //default constructor 
    { 
     for (int i = 0; i < 100; i++) 
     { 
     coef[i] = 0; 
     } 
    } 
    void set (int a , int b) //setter function 
    { 
     //coef = new Polynomial[b+1]; 
     coef[b] = a; 
     deg = degree(); 
    } 

    int degree() 
    { 
     int d = 0; 
     for (int i = 0; i < 100; i++) 
     if (coef[i] != 0) d = i; 
     return d; 
    } 

    void print() 
    { 
     for (int i = 99; i >= 0; i--) { 
     if (coef[i] != 0) { 
      cout << coef[i] << "x^" << i << " "; 
     } 
     } 
    } 

    // use Horner's method to compute and return the polynomial evaluated at x 
    int evaluate (int x) 
    { 
     int p = 0; 
     for (int i = deg; i >= 0; i--) 
     p = coef[i] + (x * p); 
     return p; 
    } 

    // differentiate this polynomial and return it 
    Polynomial differentiate() 
    { 
     if (deg == 0) { 
     Polynomial t; 
     t.set (0, 0); 
     return t; 
     } 
     Polynomial deriv;// = new Polynomial (0, deg - 1); 
     deriv.deg = deg - 1; 
     for (int i = 0; i < deg; i++) 
     deriv.coef[i] = (i + 1) * coef[i + 1]; 
     return deriv; 
    } 

    Polynomial Polynomial::operator + (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] += b.coef[i]; 
     c.deg = c.degree(); 

     return c; 
    } 

    Polynomial Polynomial::operator += (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] += b.coef[i]; 
     c.deg = c.degree(); 

     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

    Polynomial Polynomial::operator -= (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 

     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 


     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

    Polynomial Polynomial::operator *= (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) 
     for (int j = 0; j <= b.deg; j++) 
      c.coef[i+j] += (a.coef[i] * b.coef[j]); 
     c.deg = c.degree(); 

     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

    Polynomial Polynomial::operator - (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 


     return c; 
    } 

    Polynomial Polynomial::operator * (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) 
     for (int j = 0; j <= b.deg; j++) 
      c.coef[i+j] += (a.coef[i] * b.coef[j]); 
     c.deg = c.degree(); 
     return c; 
    } 
}; 

int main() 
{ 
    Polynomial a, b, c, d; 
    a.set (7, 4); //7x^4 
    a.set (1, 2); //x^2 

    b.set (6, 3); //6x^3 
    b.set (-3, 2); //-3x^2 

    c = a - b; // (7x^4 + x^2) - (6x^3 - 3x^2) 
    a -= b; 

    c.print(); 
    cout << "\n"; 


    a.print(); 
    cout << "\n"; 


    c = a * b; // (7x^4 + x^2) * (6x^3 - 3x^2) 
    c.print(); 

    cout << "\n"; 

    d = c.differentiate().differentiate(); 
    d.print(); 

    cout << "\n"; 

    cout << c.evaluate (2); //substitue x with 2 

    cin.get(); 
} 

現在,我有「 - 」操作符重載,它工作正常:

Polynomial Polynomial::operator - (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 

     return c; 
    } 

不過,我有困難我的「 - =」操作符:

Polynomial Polynomial::operator -= (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 

     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 

     // overwrite value of 'a' with the newly computed 'c' before returning 'a' 
     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

我只是稍微修改了我的「 - 」操作方法「A」和返回覆蓋值「a」,而只是使用「C」多項式作爲一個臨時。

我已經把一些調試打印語句和我確認,在計算時,既:

C = A - B;

一個 - = B;

被計算爲相同的值。

然而,當我去打印出來,其結果是不同的:

多項式A,B; a.set(7,4); // 7x^4 a.set(1,2); // x^2

b.set(6,3); // 6x^3 b.set( -3,2); // - 3x^2

c = a - b; //(7x^4 + x^2) - (6x^3 -3x^2)a - = b;

c.print(); cout < <「\ n」;

a.print(); cout < <「\ n」;

結果:

7X^4 -6x^3^4倍2

7X^4 1X^2

爲什麼我c = a - ba -= b給我不同的結果當我去打印他們?

+1

你應該申報的二進制數學運算符(包括賦值操作符,如' - =')取一個const參考輸入。另外,你應該聲明你的賦值操作符返回一個引用,並使用'return * this;'。所以,你的減-和賦值運算符應該是這樣的:'多項式與多項式::運算符 - =(常量多項式&B)'。 – 2010-04-14 19:13:14

+0

另一個錯誤:你的構造函數沒有設置「deg」。你可能要考慮使用'vector '來表示你的係數,除非你之前沒有使用它,在這種情況下它可能會有點多。 – 2010-04-14 19:18:33

回答

8

Polynomial::operator -=未修改this,它修改了this的副本。如果您將Polynomial a= *this更改爲Polynomial &a= *this,即作爲參考而不是副本,則它將像您現在正在修改*thisa一樣工作。此外,operator <op>=的返回值通常是參考值,而不是值。

+2

另外,所有參數都應該是'Polynomial const&'。 – Potatoswatter 2010-04-14 19:19:20

1

因此,首先,您可能希望將const Polynomial&而不是Polynomial傳遞給您的函數,因爲後者創建了一個副本,而前者通過常量引用傳遞。

其次,我覺得很奇怪,你正在寫:

 
Polynomial b = *this; 

而不是寫b.coeff[i]的,你可以簡單地寫coef[i],因爲它解析爲this->coef[i]。如果你絕對必須使用一些其他的變量b,雖然,那麼我建議您閱讀當您使用以下:

 
const Polynomial& b = *this; 

,並使用以下書寫時:

 
Polynomial& b = *this; 

請注意,如果您使用Polynomial代替的Polynomial&,那麼你的b變量提供是副本,是不相同的*this;因此,您所做的更改不會像預期的那樣影響*this

也就是說,寫deg = //...a.deg = //...,其中a代表*this清晰。我強烈建議你擺脫創建(試圖)參考*this變量的習慣。最後

一個說明,正如在評論已經指出,賦值運算符應該返回類型的引用。所以,你的operator=operator+=operator-=等應返回Polynomial&。這是因爲在賦值語句中允許高效的鏈接。例如:a = b = c。如果您要退回void,那麼這根本不起作用。隨着返回Polynomial的副本,它會工作,但它會neeedlessly構建副本。在這種情況下使用引用(即Polynomial&)會阻止複製。

1

運營商-=應該修改左側值(並返回對*this的引用以允許鏈接)。

這也常見於其他方面來實現這些功能:

//random example 
X& operator+= (const X& other) 
{ 
    this->sth += other.sth; 
    return *this; 
} 

//free function in terms of the previous 
//more verbose than needed for exposition 
X operator+ (const X& lhv, const X& rhv) 
{ 
    X result(lhv); 
    result += rhv; 
    return result; 
} 

事實上,大多數運營商可以(也應該)在其他方面來實現,甚至還有Boost.Operators合成從相關運營商現有的。

+1

當然,減法只是第二個操作數的負數的加法。 – JohnMcG 2010-04-14 19:18:56

+0

如果你的教授讓你使用Boost ...^_- – 2010-04-14 19:19:28