【发布时间】:2012-01-19 21:39:49
【问题描述】:
当我们在一个类中定义一个运算符函数并且我们也在一个类中定义它时,那个函数不是该类的一部分。
但是,当该函数在类之外并且我们在类中将其声明为友元但未定义它时,也可以完成相同的任务。
考虑这段代码,它有两个相同的运算符定义,一个在类内,另一个在类外:
版本 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;
}
这两种方法有什么区别?
【问题讨论】:
-
所有通过右值引用移动和返回都是没有意义的。
-
RValue 返回不是比按值返回更快吗?
-
不是没有意义,而是错误的。通过引用返回本地或临时的是未定义的行为。
-
@codekiddy:不,事实上,这完全是错误的。您正在返回对局部变量的引用。而你正在将这一举动应用于临时。它已经是一个右值,所以没有必要对它使用 move。
-
@codekiddy,一般来说,你应该避免明确地自己做任何涉及
&&或move或forward或类似的事情。当编译器知道这样做是安全的时,它会自动做正确的事情。如果你自己做,你更有可能引入错误而不是加速任何事情。事实上,所有这些 rvalueref 的东西都是精确地引入的,这样人们就可以编写简单的代码,这些代码表面上看起来很幼稚,并且通过值传递。
标签: c++ class operator-keyword friend