有时,非会员功能可能需要访问它作为一个agrument接收的私人会员。
friend
函数是一个非成员函数,可以私有访问其所有的类。
Class X{
int number;
public:
X& operator+=(const X& rhs);//a += b is a.operator(b)
friend int& operator+=(int& addthis, const X& rhs);//add this += b is I don't know what lol
}
X& operator+=(const X& rhs){
this->number = this->number + rhs.number;
}
int& operator+=(int& addthis, const X& rhs){
addthis = addthis + rhs.number;
return *this;
}
我读到的是,如果我想+=
对某个对象object += int
,只需重载+=
运算符,但如果int
出现在宾语。说int += object
?我不得不把它写成friend
函数,这就是我迷失方向的地方。为什么我不能将int& operator+=(int& addthis, const X& hrs);
写成成员函数?我假设friend
函数可以与其他类一起使用,因为它是非成员函数,所以它没有分配给任何特定的类?
对不起,我只是不明白为什么我会使用friend
功能而不是使其成为会员功能。非常感谢任何反馈,谢谢。
答案 0 :(得分:2)
您可以通过类operator+=
中用户定义的转化为int
和其他整数类型启用X
:
struct X{
int number;
operator int() const
{
return number;
}
//...
}
当然,这并不能提供与friend
- 方法完全相同的行为,因为其他功能也可以使用转换。不过,我想这就是你要找的东西,否则你需要定义operator-=
,operator*=
等等。
答案 1 :(得分:2)
据我了解,您不能拥有operator*
,operator+
或operator+=
或任何operator@
,其中@
是一些数学运算符在类的定义中返回除了类实例之外的其他内容。
在现实世界中,将整数添加到整数并将一个苹果作为结果是很奇怪的。这同样适用于C ++中的类。成员函数是类的属性,该函数表示可以对此类的对象执行的任何操作。经营者很特别。它们代表了一些不容易操作的操作(使用+
符号代替运算符重载,你会用什么来编写一个加法运算符?)。它们代表了非常基本的操作,因此应该返回它们所属的类的实例。
答案 2 :(得分:1)
运算符int += X
必须是自由函数的原因是编译器仅搜索lhs类型中的适用成员运算符,而不是rhs类型。由于int
不是可以扩展的类型,因此您无法将此运算符定义为成员函数。
你几乎就在那里,只是一些错误:
class X;
int operator+=(int addthis, const X& rhs);
class X{
int number;
public:
X& operator+=(const X& rhs);//a += b is a.operator(b)
friend int operator+=(int addthis, const X& rhs);//add this += b is I don't know what lol
};
X& X::operator+=(const X& rhs){
this->number = this->number + rhs.number;
return *this;
}
int operator+=(int addthis, const X& rhs){
addthis = addthis + rhs.number;
return addthis;
}
int
按值而不是按引用传递class
代替Class
return
已更正请注意X += int
是一个成员函数,而int += X
是一个自由函数,声明为类X的friend
。
使用int += X
的免费功能是允许像往常一样使用运算符的唯一解决方案,例如:
X x;
int i = 2;
i += x;
答案 3 :(得分:1)
考虑将运算符重载实现为成员函数并执行类似x += y
的操作,其中x
和y
都是类的对象,其中运算符+=
已重载。 / p>
编译器将x += y
解析为x.operator+=(y)
这很好,因为操作数x
和y
属于同一个类,其中运算符+=
已重载。< / p>
现在考虑像2 += y
这样的表达式(这可能是疯了,但我正在尝试解释为什么使用友元函数进行运算符重载可能对运算符重载成员函数的时间有利)
因为表达式2 += y
将由编译器解析为2.operator+=(y)
,所以会引发错误。也许2
可以使用构造函数转换为类的对象; (单个参数构造函数可用于转换)但这不是重点。
使用friend函数重载运算符会将上面的表达式2 += y
调用为operator+=(2, y)
,这样可以正常工作。
答案 4 :(得分:0)
friend
修饰符仅用于公开private
数据。通常,如果friend
函数仅依赖于类的私有数据,则它不能将ostream::operator<<
函数定义为非成员函数。它可以定义为成员函数。
更好的例子是istream::operator>>
或{{1}}。