[英]operator overloading(friend and member function)
使用friend
关键字的运算符重载和作为类中的成员函数有什么区别?
此外,任何一元运算符重载(即作为朋友与成员函数)的情况有何不同?
Jacob是正确的...在类中声明的friend
函数可以访问该类,但它根本不在类中,并且其他所有人都可以访问它。
对于不是类成员的运算符重载(也称为自由函数 ,它可能是朋友,或者可能不是),参数与操作数相同。 对于一个类的成员,第一个操作数是“隐式参数”,它成为了this
。
隐式参数在几个方面与自由函数的第一个参数不同:
virtual
重载将由第一个操作数的动态类型选择,这对于没有额外代码的自由函数是不可能的。) 对于一元,二元或n元(在operator()
的情况下operator()
,情况是相同的。
成员变异特权:更改第一个操作数的运算符(例如+=
, =
,前缀++
)应该作为成员函数实现,并且应该专门实现所有重载的内容。 Postfix ++
是一个二等公民; 它被实现为Obj ret = *this; ++ this; return ret;
Obj ret = *this; ++ this; return ret;
。 请注意,这有时会扩展到copy-constructors,它可能包含*this = initializer
。
通勤者的自由规则:只有交换运营商(例如/
)应该是自由职能; 所有其他运营商(例如一元一事)应该是成员。 交换运算符固有地制作对象的副本; 它们被实现为Obj ret = lhs; ret @= rhs; return ret;
Obj ret = lhs; ret @= rhs; return ret;
其中@
是可交换运算符, lhs
和rhs
分别是左侧和右侧参数。
C ++友谊的黄金法则:避免友谊。 friend
污染了设计的语义。 重载推论:如果你按照上面的规则重载很简单,那么friend
是无害的。 friend
样板超载定义允许它们放在class {
braces中。
请注意,某些运算符不能是自由函数: =
, ->
, []
和()
,因为标准在第13.5节中具体说明了。 我想这是所有...我想一元&
和*
太,但我显然是错误的。 尽管如此,他们应该总是作为成员超载,并且只有经过仔细考虑!
不同之处在于,friended函数实际上处于全局范围内,因此您无需成为该类的实例即可访问它。
成员函数要求左手操作符必须属于该类型。 友元函数可以允许左手操作符上的隐式转换。
成员函数要求左手操作符必须属于该类型。 友元函数可以允许左手操作符上的隐式转换。
例如,假设我们创建一个BigInt类。 我们创建了一个成员函数operator +来获取BigInt的右手操作符。
现在让我们也说BigInt有一个带有常规int的构造函数。 此构造函数不是显式的(显式关键字),它需要一个参数。 这意味着C ++可以从int转换为BigInt。
当我们有这些东西时,我们可以这样做:
BigInt foo(5); BigInt酒吧; bar = foo + 5;
但我们不能这样做:
BigInt foo(5)BigInt吧; bar = 5 + foo;
但是,如果我们使用友元函数而不是成员函数,那么两者都可以工作。
可以在rvalues上调用成员函数,而不能使用rvalues调用接受对非const的引用的自由函数。 例如, ++function_returning_iterator_by_value()
仅在您将operator++
实现为成员时才编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.