2012-01-19 41 views
0

当我们在一个类中定义一个操作符函数时,我们也在类中定义它,那么该函数不是类的一部分。C++类,朋友操作符与外部操作符的区别是什么

但同样的任务是当该函数在类之外并且我们将其声明为类内的朋友但未定义它时,就会执行相同的任务。

考虑下面的代码,其具有两个相同的操作者定义,其中一个是类内的另一ouside类:

版本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

所有移动和返回右值引用是没有意义的。 –

+0

是不是通过RValue返回更快然后返回值? – codekiddy

+0

不是毫无意义,而是错误的。通过引用返回本地或临时是未定义的行为。 –

回答

1

目前,您在第一个片段中定义了两次MyClass&& operator +(MyClass& a, MyClass& b),第二次定义了一次。如果删除第二个定义,则两者在语义上是等同的。

这两者会做同样的事情。在某些情况下,可能会优先于另一个(例如,第二个可以放在cpp文件中,第一个可能更适合使用模板)。

请注意,第一个是隐式标记为内联,第二个不是。

(你应该常引用路过MyClass,虽然)。

+0

哦,谢谢我纠正了我的第一个片段。所以现在纠正的那两个片段完全相同? – codekiddy

+0

@codekiddy:已更新以反映更改。 –

+0

哦,是的,模板和内联使得sence。谢谢! – codekiddy

4

在你的情况,这两个版本做同样的事情(返回悬空参考,实际上,导致未定义的行为),虽然一个是inline和两个不是。

一般而言,在类内部定义主体的友元函数也可以不带限定地使用类成员(由于在朋友函数中没有this指针,所以它们可能是静态成员,可能在基类中)。

下面是标准的相关文本(第11.3 [class.friend]):

函数可德网络定义的一类朋友的声明,当且仅当类是一个非本地类(9.8) , 函数名称是不合格的,函数具有命名空间范围。

这样的函数隐含地为inline。定义在类中的函数在它所定义的类的(词汇)范围内。在类外定义的函数不是(3.4.1)。