重载大于有或没有友元的运算符
overload greater than operator with or without friend
假设我有以下 class:
class Point{
private:
int x,y;
public:
int get_x() const {return x;}
int get_y() const {return y;}
Point() :x(0),y(0){}
Point(int x,int y):x(x),y(y){}
Point(const Point& P){
x = P.get_x();
y = P.get_y();
}
Point& operator= (const Point& P) {
x = P.get_x();
y = P.get_y();
return *this;
}
friend ostream& operator<<(ostream& os,const Point& P) {
os<<"["<<P.get_x()<<", "<<P.get_y()<<"]";
return os;
}
Point operator - (const Point &P){
return Point(x-P.get_x(),y-P.get_y());
}
friend bool operator > (const Point &A, const Point &B) {
return A.get_y()>B.get_y();
}
};
这里我用到了友元功能。我也可以在没有朋友的情况下使用功能:
class Point{
...
bool operator > (const Point &B) const {
return y>B.get_y();
}
...
};
它们在实际实现中有什么区别?同样在第二种方法中,没有 'cont' 代码将无法编译,这是为什么?即使在我将 getter 函数更改为非常量函数之后,如果没有 'const'.
它仍然无法编译
您已经注意到,比较运算符重载可以实现为成员函数或非成员函数。
作为 rule of thumb 你应该尽可能将它们实现为非成员非 friend
函数,因为这增加了封装,并且它允许 (non-explicit
) 转换运算符两侧使用的构造函数。
比如说你的 Point
class 出于某种原因有一个 int
转换构造函数:
Point(int x);
使用非成员比较运算符,您现在可以执行以下操作:
Point p;
p < 3; // this will work with both a member and non-member comparison
3 < p; // this will **only** work if the comparison is a non-member function
您似乎也对何时使用 const
感到困惑,再次作为比较运算符的经验法则,您应该尽可能始终使用 const
,因为比较逻辑上不涉及任何更改到对象。
由于 Point
非常小 class 您也可以按值取用它,因此按照从最优选到最不优选的顺序,您的选择是:
// Non-member, non-friend
bool operator>(Point const& A, Point const& B);
bool operator>(Point A, Point B);
// Non-member, friend
friend bool operator>(Point const& A, Point const& B);
friend bool operator>(Point A, Point B);
// Member
bool Point::operator>(Point const& B) const;
bool Point::operator>(Point B) const;
假设我有以下 class:
class Point{
private:
int x,y;
public:
int get_x() const {return x;}
int get_y() const {return y;}
Point() :x(0),y(0){}
Point(int x,int y):x(x),y(y){}
Point(const Point& P){
x = P.get_x();
y = P.get_y();
}
Point& operator= (const Point& P) {
x = P.get_x();
y = P.get_y();
return *this;
}
friend ostream& operator<<(ostream& os,const Point& P) {
os<<"["<<P.get_x()<<", "<<P.get_y()<<"]";
return os;
}
Point operator - (const Point &P){
return Point(x-P.get_x(),y-P.get_y());
}
friend bool operator > (const Point &A, const Point &B) {
return A.get_y()>B.get_y();
}
};
这里我用到了友元功能。我也可以在没有朋友的情况下使用功能:
class Point{
...
bool operator > (const Point &B) const {
return y>B.get_y();
}
...
};
它们在实际实现中有什么区别?同样在第二种方法中,没有 'cont' 代码将无法编译,这是为什么?即使在我将 getter 函数更改为非常量函数之后,如果没有 'const'.
它仍然无法编译您已经注意到,比较运算符重载可以实现为成员函数或非成员函数。
作为 rule of thumb 你应该尽可能将它们实现为非成员非 friend
函数,因为这增加了封装,并且它允许 (non-explicit
) 转换运算符两侧使用的构造函数。
比如说你的 Point
class 出于某种原因有一个 int
转换构造函数:
Point(int x);
使用非成员比较运算符,您现在可以执行以下操作:
Point p;
p < 3; // this will work with both a member and non-member comparison
3 < p; // this will **only** work if the comparison is a non-member function
您似乎也对何时使用 const
感到困惑,再次作为比较运算符的经验法则,您应该尽可能始终使用 const
,因为比较逻辑上不涉及任何更改到对象。
由于 Point
非常小 class 您也可以按值取用它,因此按照从最优选到最不优选的顺序,您的选择是:
// Non-member, non-friend
bool operator>(Point const& A, Point const& B);
bool operator>(Point A, Point B);
// Non-member, friend
friend bool operator>(Point const& A, Point const& B);
friend bool operator>(Point A, Point B);
// Member
bool Point::operator>(Point const& B) const;
bool Point::operator>(Point B) const;