我有超载两个问题。
1为什么有时候会令运算符重载的非成员函数?
friend Class operator-(const Class &rhs);
2-什么之间的区别
Class operator+(const Class &c1, const Class &c2);
和
Class operator+(const Class &rhs);
如果我想补充两个对象C3 = C1 + C2
?
任何帮助表示赞赏...
我有超载两个问题。
1为什么有时候会令运算符重载的非成员函数?
friend Class operator-(const Class &rhs);
2-什么之间的区别
Class operator+(const Class &c1, const Class &c2);
和
Class operator+(const Class &rhs);
如果我想补充两个对象C3 = C1 + C2
?
任何帮助表示赞赏...
如果你重载二元运算符为成员函数,它结束了不对称:左边的操作数必须是该运营商超载的确切类型,但右操作数可以是任何可以转换为正确的类型。
如果您与非成员函数重载运算符,则两个操作数可以转换,以获得正确的类型。
你作为你的第二个观点是什么样子的相同点,算不上什么独立可言的具体例子。 下面是我在谈论的一个具体的例子:
class Integer {
int val;
public:
Integer(int i) : val(i) {}
operator int() { return val; }
// Integer operator+(Integer const &other) const { return Integer(val + other.val); }
friend Integer operator+(Integer const &a, Integer const &b) {
return Integer(a.val + b.val);
}
};
int main() {
Integer x(1);
Integer y = x + 2; // works with either operator overload because x is already an Integer
Integer z = 2 + x; // works with global overload, but not member overload because 2 isn't an Integer, but can be converted to an Integer.
return 0;
}
还要注意的是,即使定义friend
的功能是类定义里面Integer
,它被声明的事实作为一个朋友就是它不是一个成员函数-它声明为friend
成为全球性的功能,而不是一个成员。
底线:这种过载通常应做免费的功能,而不是成员函数。 为用户提供的是正常工作(大幅)胜过理论上的考虑,如“面向多个对象”操作。 必要时,例如当操作的实现需要是虚拟的,你可以做一个两步的版本,在那里你提供一个(可能是虚拟的)成员函数,它真正的工作,但超载本身就是一个免费的功能调用在其左侧操作数的成员函数。 这方面的一个比较常见的例子是超载operator<<
一个层次:
class base {
int x;
public:
std::ostream &write(std::ostream &os) const {
return os << x;
}
};
class derived : public base {
int y;
public:
std::ostream &write(std::ostream &os) const {
return (base::write(os) << y);
}
};
std::ostream &operator<<(std::ostream &os, base const &b) {
return b.write(os);
}
这同时支持多态的实现(并获得了基类的保护成员,如果需要的话)没有放弃运营商的正常特性得到它。
主例外重载二进制运算符作为免费功能是赋值运算( operator=
, operator+=
, operator-=
, operator*=
等等)。 A转换会产生一个临时对象,你不能分配给反正,所以对于这种特殊情况下,过载应为(必须是,作为事实上)成员函数。
1,为什么有时候会令运算符重载的非成员函数?
这是选择的问题。 您可以让operator +/-
类成员,或者使它成为一个自由friend
功能。
您提供的语法 operator -
是错的,如果它是一个免费的friend
的功能,它应该采取2个参数(类似于operator +
在你的例子)。
2-什么之间的区别
正如前面所说的,它只是一个不同的语法。 第一个应该是一个自由friend
功能,第二个是一class
构件。
最重要的是,我相信保持操作的class
成员方法优于比较自由的功能,因为:
protected
基类(如果适用)的成员,但friend
功能不能 使重载的运算符的朋友是一个更好的选择,因为拿这个例子
class Comples
{
public:
Complex(float real, float imaginary);
friend operator+ (const Complex &rhs);
...
};
通过使操作者的朋友,你可以做以下
Complex result1 = 5.0 + Comples(3.0, 2.0);
和
Complex result1 = Comples(3.0, 2.0) + 5.0;
其遵循添加communitivity属性的规则。 如果重载操作者是一个成员函数这是无法实现的。 这是因为编译器能够隐含创建一个Complex
在这种情况下asrequired对象。 因此是朋友,当加法运算作用于按照另外在数学正常概念。