操作员重载功能

时间:2019-02-04 08:57:11

标签: c++ operator-overloading

我对2个非成员,2个非朋友乘法和运算符重载函数的添加感到困惑。我不确定该怎么做。有人可以协助我解决这个问题吗?请参阅下面的代码。先感谢您!

编译器输出:

Point.cpp:208:19: error: passing ‘const CS170::Point’ as ‘this’ argument discards qualifiers [-fpermissive]

    return other + value;
                   ^~~~~

Point.cpp: In function ‘CS170::Point CS170::

operator*(double, const CS170::Point&)’:

Point.cpp:215:10: error: ‘double CS170::Point::x’ is private within this context

   result.x = value * x;
          ^

Point.cpp:215:22: error: ‘x’ was not declared in this scope

   result.x = value * x;
                      ^
Point.cpp:216:10: error: ‘double CS170::Point::y’ is private within this context

   result.y =  value * y;
          ^

Point.cpp:216:23: error: ‘y’ was not declared in this scope
   result.y =  value * y;

Point.h

  #include <iostream> // istream, ostream

  namespace CS1100
{
  class Point
  {
   public:
  // Point(double X, double Y);    // Constructors (2)
  explicit Point(double x, double y); 

   Point();

   Point operator+(const Point& other)const ;

   Point& operator+(double value);


   Point operator*(double value) ;

   Point operator%(double value);


   Point operator-(const Point& other)const ;

   Point operator-(double value);

   Point operator^(const Point& other);

   Point operator+=(double value);
   Point& operator+=(const Point& other) ;

   Point& operator++();
   Point operator++(int); 

   Point& operator--(); 
   Point operator--(int); 

   Point& operator-();


        // Overloaded operators (14 member functions)
   friend std::ostream &operator<<( std::ostream &output, const Point &point );
    friend std::istream &operator>>( std::istream  &input, Point &point );

    // Overloaded operators (2 friend functions)

private:
  double x; // The x-coordinate of a Point
  double y; // The y-coordinate of a Point

    // Helper functions
  double DegreesToRadians(double degrees) const;
  double RadiansToDegrees(double radians) const;
 };

 // Point& Add(const Point& other); // Overloaded operators (2 non-member, non-friend functions)
    // Point& Multiply(const Point& other);
    Point operator+( double value, const Point& other );
    Point operator-( double value, const Point& other );

我的源代码:

///////////////////////////////////////////////////////////////////////////////
// 2 non-members, non-friends (operators)


double operator+( double value, const Point& other ) 
{
     return other + value;
}   

double operator*( double value, const Point& other ) 
{

    Point result;
    result.x = value * x;
    result.y =  value * y;
    return result;
}   

1 个答案:

答案 0 :(得分:1)

据我所知,对问题的讨论实际上并不是操作员本身,而是所允许的成员函数数量受到限制–您已经超出了此限制。

但是,您有很多不需要成为成员的函数,例如:

class Point
{
public:
    Point operator+(const Point& other) const
    {
        return Point(x + other.x, y + other.y);
    }
};

从所有这些功能中释放功能:

class Point { /*...*/ };

Point operator+(Point const& l, Point const& r)
{
    return Point(l.getX() + r.getX(), l.getY() + r.getY());
}

已经将所有这些运算符都移出了上面所示的运算符之后,您就远远超出了限制,可以引入所需的吸气剂:

class Point
{
public:
    double getX() { return x; };
    double getY() { return y; };
};

如果您愿意重命名成员变量,请执行e。 G。通过添加前缀,您可以遵循另一种模式:

class Point
{
    double m_x, m_y;
public:
    double x() { return m_x; };
    double y() { return m_y; };

    void x(double v) { m_x = v; }; // the corresponding setter
                                   // (for illustration, you might not need it)
};

后一种模式也很常见。跳过显式getset前缀的优点是较短,缺点是恰恰失去了这种显性...决定您,选择您喜欢的那个。但是,比个人喜好更重要的是保持一致性,所以如果存在e。 G。公司的惯例或惯例,请遵循该惯例...

您的某些操作员将需要保留其成员身份,但是这些都是对当前对象进行修改的成员:

class Point
{
public:
    Point& operator+=(const Point& other) /* const */ // NEEDS to be non-const
    {
        x += other.x;
        y += other.y;
        return *this; // <- very good hint to spot the ones needing to stay members
    }
};

如果您有公共的 copy 构造函数,则可以重新使用operator+=来定义operator+

class Point
{
public:
    Point(Point const& other) : Point(other.x, other.y) { }
};

Point operator+(Point const& x, Point const& y)
{
    Point r(x); // or Point(x.x(), x.y()), if you lack such constructor)
    r += y;
    return r;
}

实际上,您甚至可以通过按值接受参数之一来保留显式副本:

Point operator+(Point x, Point const& y)
//                    ^ no reference
{
    return x += y;
}

后者只是为了说明,我希望在给定情况下使用两个引用来保持界面的对称性...