我正在进行以下多项式课程:
#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;
和
a - = 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); // - 3×^ 2
c = a - b; //(7x ^ 4 + x ^ 2) - (6x ^ 3 - 3x ^ 2)a - = b;
c.print(); cout&lt;&lt; “\ n” 个;
a.print(); cout&lt;&lt; “\ n” 个;
结果:
7x ^ 4 -6x ^ 3 4x ^ 2
7x ^ 4 1x ^ 2
为什么我的c = a - b
和a -= b
在打印时会给我不同的结果?
答案 0 :(得分:8)
Polynomial::operator -=
未修改this
,它正在修改this
的副本。如果您将Polynomial a= *this
更改为Polynomial &a= *this
,即创建引用而不是副本,则可以使用*this
到a
进行修改。此外,operator <op>=
的返回值通常是引用,而不是值。
答案 1 :(得分: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
的副本,它将起作用,但它将无需构建副本。在这种情况下使用引用(即Polynomial&
)可防止复制。
答案 2 :(得分: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来合成现有运营商的相关运营商。