2017-02-26 98 views
2

有代码友元函数声明为成员函数

struct node 
{ 
    node(int X , int Y):X(X),Y(Y){}; 
    int X; 
    int Y; 
    friend bool operator ==(const node &X, const node &Y); 
}; 


int main() 
{ 
    node one(5,5); 
    node two(5,5); 
    if (one == two) 
    { 
     cout << " true " << endl; 
    } 
    return 0; 
} 

如果我声明的==操作符作为

bool node::operator ==(const node &X, constnode &Y) 
{ 
    return (X.X == X.Y && Y.X == Y.Y); 
} 

它需要一个参数,但是当我把它声明为

bool operator ==(const node &X, constnode &Y) 
{ 
    return (X.X == X.Y && Y.X == Y.Y); 
} 

它需要两个。我知道由语言定义,第一个定义需要一个参数,因为第二个是* this。

而第二个定义是它的运算符==(全局)的外部定义,它不绑定到任何结构,它不会传递* this在它中。

但是它还是定义为“朋友”这个基本说明(第一个定义)成员函数是它自己类的朋友函数。这怎么可能?为什么编译?

+0

'布尔节点::运算符==(const的节点&X,常量节点&Y)'将需要3个参数(成员函数都隐含'this'参数)。 –

+0

除了语言特定的问题,请注意您的布尔评估应该是'XX == YX && XY == YY' ** not **'XX == XY && YX == YY' –

+0

其实不应该命名这样的参数首先是为了避免混淆。一种常见的做法是将它们命名为“lhs”(左侧)和“rhs”(右侧)。 – zett42

回答

3

声明为朋友的方法实际上不是类的方法,而是类之外的全局函数,与类相同的名称空间。

所以下面的内嵌定义...

struct node 
{ 
    node(int X , int Y):X(X),Y(Y){}; 
    int X; 
    int Y; 
    friend bool operator ==(const node &lhs, const node &rhs) { 
     return (lhs.X == rhs.X && lhs.Y == rhs.Y); 
    } 
}; 

...是一样的...

bool operator ==(const node &lhs, const node &rhs) 
{ 
    return (lhs.X == rhs.X && lhs.Y == rhs.Y); 
} 

这就是为什么你的运营商的第一个定义==不是有效定义为声明为朋友的方法。

如果你在类的外部定义了全局运算符==,那么如果全局函数需要访问该类的私有成员,你实际上只需要朋友声明。在你的情况下,这不是必需的,因为X和Y是公开的。

+0

您是否注意到在检查两个节点的等式的方程中有什么错误? –

+0

好地方!固定... – zett42

+0

现在很好。 OP中的初始代码通过为对象及其属性使用相同的名称来寻找麻烦,因此很容易被困住。将这些名称改为“lhs”和“rhs”几乎是必须的。 –

0

这是因为第一个定义使节点的operator ==成员函数。因此它可以访问这个指针,所以第一个指针隐式地是这个,你可以继续使用一个参数。

第二个定义使得节点的operator == friend功能。现在,friend函数通过获取它们的引用来访问类的成员,因为它无法访问此指针。因此我们需要指定两个参数。

希望它可以帮助