首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写一个重载的operator+函数,以便可以将二次类的两个实例添加到一起,如下面的代码所示:

编写一个重载的operator+函数,以便可以将二次类的两个实例添加到一起,如下面的代码所示:
EN

Stack Overflow用户
提问于 2010-09-14 08:16:11
回答 3查看 1.3K关注 0票数 0

编写一个重载的operator+函数,以便可以将二次类的两个实例添加到一起,如下面的代码所示:

代码语言:javascript
复制
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;

为了帮助您,下面是两个number函数的实现:

代码语言:javascript
复制
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;
}

拼命地寻求上师的帮助!任何帮助都将不胜感激!

EN

回答 3

Stack Overflow用户

发布于 2010-09-14 08:21:53

从所提供的函数可以明显看出,二次函数(至少)有三个成员变量,a、b和c:

代码语言:javascript
复制
class quadratic
{
public:
//...
private:
  double a, b, c;
};

此外,我们可以推断quadratic有一个接受3个doubles的构造函数和一个operator+:

代码语言:javascript
复制
class quadratic
{
public:
  quadratic(double A, double B, double C) {/*...*/}
  quadratic operator+(const quadratic &other) {/*...*/}
  //...
private:
  double a, b, c;
};

在剩下的实现中,您遇到了哪些问题?

票数 0
EN

Stack Overflow用户

发布于 2010-09-14 16:16:57

简单的方法是使用一些如意算式:在编写加法操作之前,只需假设您确实拥有这两个对象。

实际上,当您定义操作时,您正在编写一个稍后将应用的算法。在调用位置,当某些用户键入a+bab时,它们必须是您要添加的类型的有效实例。在定义操作时,函数或方法的参数表示稍后将存在的有效实例的参数。

由于这是家庭作业,我将遵循一个不同的例子。考虑编写一个vector2d类,其中包含表示xy坐标的两个双精度值。

代码语言:javascript
复制
class vector2d {
public:
   //...
private:
   double x,y;
};

并且您希望提供一些可以应用于vector2d对象的操作。您可以将operator+=定义为在向量中存储同一向量与第二个向量相加的结果的一种方式:

代码语言:javascript
复制
class vector2d {
public:
   //...
   vector2d& operator+=( const vector2d& rhs )
   {
      x += rhs.x;
      y += rhs.y;
      return *this;
   }
};

对于约定,我们从operator+=返回一个对vector2d的引用。我们既对调用该操作的对象(这是一个成员函数,即*this对象)进行操作,也对另一个作为参数的对象进行操作。注意,此时没有在程序中创建单个对象,我们只是定义操作,而不是操作数。右边的参数rhs是通过一个常量引用来处理的(我们得到了一个对我们承诺不会改变的对象的引用)。实际操作很简单,分别添加每个坐标,并且因为约定返回对修改后的对象的引用,所以我们返回*this

我们已经根据两个对象定义了如何执行操作,现在我们可以使用它了:

代码语言:javascript
复制
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;
}

现在,为了能够进行调用,用户需要有两个对象。为了定义操作,我们实际上不需要对象的实例,我们通过参数对其进行抽象。但要实际使用操作,我们确实需要要操作的对象。在这一点上,它们实际上被创建并命名为ab。然后,用户调用该操作:a += b。因为它是一个成员方法,调用被编译器翻译成一些不太漂亮的东西:a.operator+=(b),也就是说,它将在对象a上调用成员方法operator+=,并将b作为参数传递。

为了提供适当的加法运算,我们可以编写一个自由函数。加法并不适用于这两个参数中的任何一个,而是创建了第三个参数,因此它不是成员方法是有意义的。

代码语言:javascript
复制
vector2d operator+( vector2d lhs, const vector2d & rhs )
{
   lhs += rhs;
   return lhs;
}

这个实现是惯用的(一种常见的模式)。一旦我们实现了operatorX=,我们就可以按照前面的方式实现operatorX了。现在的诀窍是:我们通过值来获取第一个参数。这样编译器就会为我们制作一个副本,这个函数中的lhs不是加法的第一个参数,而是它的一个副本。然后,我们使用现有操作修改该本地副本,并将结果返回给用户。返回的对象也是按值返回的。

用法类似:

代码语言:javascript
复制
int main() {
   vector2d a( 5, 10 );
   vector2d b( 2.5, 7.5 );
   vector2d c = a + b;
}

在调用的地方,a+b被转换为operator+( a, b ),因为它是一个自由函数。然后,因为第一个参数是通过值传递的,所以将创建a的副本并用作函数中的lhs。第二个参数是通过引用传递的,我们承诺不会更改它(因此是const)。操作的结果存储在c中。

票数 0
EN

Stack Overflow用户

发布于 2010-09-14 16:46:23

所以..。你想声明这个函数吗?

代码语言:javascript
复制
quadratic operator+(const quadratic& LHS, const quadratic& RHS);

将其实现为?

代码语言:javascript
复制
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::getCoefficientsquadratic::evaluate确实应该对调用对象有恒定的保护。而且,您很可能只对单个组件使用像inline const double& quadratic::getA() const这样的方法。这可能具有较少的内存和处理开销,并且不允许修改组件,尽管它通过引用返回。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3705323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档