当我们在一个类中定义一个operator函数时,我们也在一个类中定义它,然后该函数不属于该类。
但是当该函数在类之外并且我们将它声明为类中的朋友但未定义它时,也会执行相同的任务。
考虑这个代码有两个相同的运算符定义,其中一个在类中,另一个在类中:
版本1(在课堂内)
class MyClass
{
// version 1 inside a class
friend MyClass&& operator +(MyClass& a, MyClass& b)
{
return move(MyClass(a.x + b.x, a.y + b.y));
}
int x,y;
public:
MyClass() {}
MyClass(int,int){}
};
int main()
{
MyClass a, b, c;
c = a + b;
cin.ignore();
return 0;
}
版本2(课外)
class MyClass
{
friend MyClass&& operator +(MyClass& a, MyClass& b);
int x,y;
public:
MyClass() {}
MyClass(int,int){}
};
MyClass&& operator +(MyClass& a, MyClass& b)
{
return move(MyClass(a.x + b.x, a.y + b.y));
}
int main()
{
MyClass a, b, c;
c = a + b;
cin.ignore();
return 0;
}
这两种方法有什么不同?
答案 0 :(得分:4)
在你的情况下,两个版本做同样的事情(返回一个悬空引用,实际上,导致未定义的行为),虽然一个是inline
而两个不是。
通常,在类中定义了body的friend函数也可以使用没有限定的类成员(那些是静态成员,可能在基类中,因为在友元函数中没有this
指针。
以下是标准中的相关文字(第11.3节[class.friend]
):
当且仅当该类是非本地类时,函数才能在类的朋友声明中定义(9.8), 函数名称是不合格的,函数具有命名空间范围。
这样的功能是隐含的
inline
。类中定义的friend
函数位于定义它的类的(词法)范围内。在类外定义的friend
函数不是(3.4.1)。
答案 1 :(得分:1)
目前,您在第一个片段中定义 MyClass&& operator +(MyClass& a, MyClass& b)
两次,在第二个片段中定义一次。如果删除第二个定义,则两者在语义上是等效的。
这两个人会做同样的事情。在某些情况下,一个可能比另一个更受欢迎(例如,第二个可以放在cpp
文件中,第一个可能更自然的模板。)
请注意,第一个是内联隐式标记,第二个不是。
(你应该通过const引用传递MyClass
。)