繁体   English   中英

运算符重载(朋友和成员函数)

[英]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; 其中@是可交换运算符, lhsrhs分别是左侧和右侧参数。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM