C ++中的运算符重载+运算符。如何重载objecttypeA + ObjectypeA = Objectype B?

时间:2015-09-28 12:45:04

标签: c++ operator-overloading

我有两节课。 Class OnePoint和Class Line。

OnePoint由一个点,两个坐标组成。

一个类线由两个点组成,两个OnePoint对象。

如何添加两个OnePoints以使其成为运算符重载的行?

OnePoint a(3.0, 3.0); 
OnePoint b(1.0, 1.0); 

Line d; 

d = a+b; 

cout << d;

变为{(3.0,3.0),(1.0,1.0)}

#include <iostream>
using namespace std;

class OnePoint {
private:
    double xvalue;
    double yvalue;

public:
    OnePoint(double x = 0.0, double y = 0.0) {
        xvalue = x;
        yvalue = y;

    }

    friend ostream& operator<<(ostream& printh, OnePoint& cPoint) {
        printh << "(" << cPoint.xvalue << ',' << cPoint.yvalue << ")";
        return printh;

    }

    void Plus(OnePoint a) {
        xvalue = xvalue + a.xvalue;
        yvalue = yvalue + a.yvalue;
    }

    void Minus(OnePoint b) {

        xvalue = xvalue + b.xvalue;
        yvalue = yvalue + b.yvalue;

    }

    OnePoint Plustwo(OnePoint a) {
        return (xvalue + a.xvalue, yvalue - a.yvalue);

    }

    void Change(double a, double b) {
        xvalue += a;
        yvalue += b;
    }

    void Print(OnePoint b) {

        cout << xvalue << "," << yvalue << endl;

    }

    /*OnePoint operator-(OnePoint a) {
        OnePoint temp;
        temp.xvalue = xvalue + a.xvalue;
        temp.yvalue = yvalue + a.yvalue;

        return temp;

    }


    friend OnePoint operator+(OnePoint a, OnePoint b) {
        OnePoint temp;
        temp.xvalue = a.xvalue + b.xvalue;
        temp.yvalue = a.yvalue + b.yvalue;

        return temp;

    }*/


};



class Line {
private: 
    OnePoint onevalue; 
    OnePoint twovalue; 
public: 
    Line(OnePoint a, OnePoint b) {
        onevalue = a; 
        twovalue = b; 

    }

    /*OnePoint getonevalue() {
        return onevalue; 
    }

    OnePoint gettwovalue() {

        return twovalue; 
    }*/

    friend ostream& operator<<(ostream& print, Line& cLine){
        print << "{"<< cLine.onevalue << ',' << cLine.twovalue << "}"; 
        return print; 
    }

    friend Line operator+(OnePoint a, OnePoint b) {
        Line temp;                                    // I have been trying 
        temp(a, b);                           //something here without luck

        return temp;
    }

};



-------------------------------------------------------------------------------
int main(){

    OnePoint a(3.0, 3.0); 
    OnePoint b(1.0, 1.0);  

    Line d(a, b); 



    cout << a << endl;

    cout << d << endl; 

    }

4 个答案:

答案 0 :(得分:2)

你可以重写(在C ++ 11中)你的operator +喜欢

Line operator+(const OnePoint& lhs, const OnePoint& rhs)
{
    return {lhs, rhs};
}

答案 1 :(得分:1)

所有你需要做的 - 不做任何改变 - 是

OnePoint a(3.0, 3.0);
OnePoint b(1.0, 1.0); 
Line d(a,b);

如果你真的想做

d = a + b;

然后您需要提供一个operator+(),它接受​​两个类型为OnePoint的参数,并返回Line。替代方案是作为OnePoint

的成员进行的
 // definition of Line here

class OnePoint
{
    public:
        Line operator+(const OnePoint &) const;

         //  other member functions, etc 
};

Line OnePoint::operator+(const OnePoint &rhs) const
{
     Line retval(*this, rhs);
     return retval;
}

或作为非会员

 // definitions of Line and OnePoint here

 Line operator+(const OnePoint &lhs, const OnePoint &rhs);   // declaration, not definition

 Line operator+(const OnePoint &lhs, const OnePoint &rhs)
 {
      Line retval(lhs, rhs);
      return retval;
 }

显然,在上述两种情况下,我都假设operator+()可以根据需要访问(例如Line&#39;构造函数)。

请注意,从数学上讲,您所做的是向后的。不使用a+b语法添加点来获取一条线 - 使用一对点而不是求和来表示线。相反,向量被添加到点以产生其他点。

答案 2 :(得分:0)

你的错误非常微不足道。您的Line类构造函数是多参数构造函数,您需要使用Line类型的两个参数构造OnePoint对象。

我已经纠正了你的代码,如果构造函数需要一个或多个参数,你就会知道如何构造类的对象。

friend Line operator+(OnePoint a, OnePoint b) {
            Line temp(a,b);                                    // Changed here
            return temp;
        }

您还可以通过此link了解有关对象构建的基础知识

答案 3 :(得分:0)

请勿覆盖+来执行此操作。这是非常意外的。

如果您确实需要干净的语法,请使用命名运算符。

这是一个12行named operator library

namespace named_operator {
  template<class D>struct make_operator{make_operator(){}};

  template<class T, char, class O> struct half_apply { T&& lhs; };

  template<class Lhs, class Op>
  half_apply<Lhs, '*', Op> operator*( Lhs&& lhs, make_operator<Op> ) {
    return {std::forward<Lhs>(lhs)};
  }

  template<class Lhs, class Op, class Rhs>
  auto operator*( half_apply<Lhs, '*', Op>&& lhs, Rhs&& rhs )
  -> decltype( invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) ) )
  {
    return invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) );
  }
}

然后我们使用上面的库定义一个实际的命名运算符,如下所示:

struct line_to_tag {}; // tag type
static const named_operator::make_operator<line_to_tag> line_to; // name of operator

// action from operator:
Line invoke( OnePoint lhs, line_to_tag, OnePoint rhs ) {
  return Line(lhs, rhs);
}

现在可行:

Point a, b;
Line l = a *lineto* b;

我认为比a+b更清楚。 (是的,命名运算符库有点令人困惑,但使用点的代码非常清楚)。