朋友和内联方法,有什么意义? [英] friend AND inline method, what's the point ?

查看:93
本文介绍了朋友和内联方法,有什么意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在标题中看到,我没有写自己以下内容:

 类MonitorObjectString:public MonitorObject {
//一些其他声明
friend inline bool operator ==(MonitorObjectString& lhs,MonitorObjectString& rhs){return(lhs.fVal == rhs.fVal); }



我不明白为什么这个方法被声明为朋友。我认为如果函数定义在另一个地方,需要访问classe的内部成员,但这不是这里的情况,因为它是内联的,甚至不需要访问成员。 / p>

你觉得怎么样?是朋友无用?

解决方案

  friend inline bool operator ==(MonitorObjectString& lhs,MonitorObjectString& rhs){ 
return(lhs.fVal == rhs.fVal);
}

称为朋友定义。它将函数定义为它出现的类周围的命名空间的非成员函数。实际上,内联存在冗余:如果它是一个朋友定义,它被隐式声明为inline。它的一些优点和缺点:




  • 这使得操作员对于正常查找不可见。你可以调用它的唯一方法是使用参数取决于查找。这将保持命名空间没有大量正常可见的运算符声明。注意,这也将禁用使用隐式转换为MonitorObjectString调用它的能力(因为如果两个参数类型在查找候选项时被调用时不匹配,那么依赖于参数的查找将找不到该函数)。

  • 对于名称的查找在朋友定义出现的类的范围内开始。这意味着不需要长类型名称或其他名称。

  • 由于它是一个朋友,函数会看到 MonitorObjectString 。但这不是好还是坏。这取决于情况。例如,如果有函数 getFVal()使函数的朋友是相当无意义。可以使用 getFVal



我习惯喜欢这种运算符的朋友定义风格,因为它们可以直接访问类成员,并出现在类定义中 - 所以我可以有一切一切。然而,最近,我得出结论,这并不总是一个好主意。如果你可以(和你应该)实现运算符纯粹使用类的公共成员函数,你应该使它成为一个非朋友(和非成员)运算符,在类的同一命名空间中定义。它确保如果你改变一些实现 - 但保持类的接口相同 - 操作员仍然工作,你有较少的级联更改,因为你知道它不能访问实现细节。



,我更喜欢这种风格的写成员操作符,因为在命名空间范围的操作符函数具有与其参数对称的附加功能:他们不处理左侧特殊,因为两侧只是正常的参数,而不是绑定到 * this 的对象参数。如果左侧或右侧是类的类型,则另一侧可以隐式转换 - 忽略它是左还是右。对于也没有友元定义语法(传统上,在命名空间范围)定义的函数,您将有选择性地包括使这些运算符可用或不可用的标头的功能。


I see in a header that I didn't write myself the following :

class MonitorObjectString: public MonitorObject {
   // some other declarations
   friend inline bool operator==(MonitorObjectString& lhs, MonitorObjectString& rhs) { return(lhs.fVal==rhs.fVal); }

I can't understand why this method is declared as friend. I thought it would make sense if the function is defined in another place and need to access the internal member of the classe, but this is not the case here as it is inline and doesn't even need to have access to the members.

What do you think ? is the "friend" useless ?

解决方案

friend inline bool operator==(MonitorObjectString& lhs, MonitorObjectString& rhs) { 
    return(lhs.fVal==rhs.fVal); 
}

is called friend definition. It will define the function as a non-member function of the namespace surrounding the class it appears in. Actually, the inline there is redundant: It's implicitly declared inline if it's a friend definition. Some pros and cons of it:

  • It makes the operator not visible to normal lookup. The only way you can call it is using argument depending look-up. This will keep the namespace free of lots of operator declarations visible normally. Note that this will also disable ability of calling it using implicit conversions to MonitorObjectString (because if both argument types do not match at the time of looking for candidates to be called, argument dependent look-up won't find the function).
  • The lookup for names starts in the scope of the class the friend definition appears in. This means that no long type-names or other names are needed to be written out. Just refer them as you would in a normal member function of the class.
  • As it is a friend, the function sees the internals of MonitorObjectString. But that's neither good nor bad. It depends on the situation. For example if there are functions getFVal() making the function friend is pretty pointless. Could use getFVal as-well then.

I used to like this friend definition style of operators, because they have direct access to class members, and appear within the class definition - so i could have "everything with one sight". Recently, however, i came to the conclusion that it's not always a good idea. If you can (and you should) implement the operator purely using public member functions of the class, you should make it a non-friend (and non-member) operator, defined in the same namespace of the class. It makes sure that if you change some implementation - but keep the interface of the class the same - the operator will still work and you have less cascading changes, because you know it can't access implementation details.

However, i prefer this style over writing member operators, because operator functions at namespace scope have the added features of being symmetric with their arguments: They don't treat the left side special, because both sides are just normal arguments and not object arguments that are bound to *this. If either the left or the right side is of the type of your class, the other side can be implicitly converted - disregarding of whether it's left or right. For functions that are also defined without the friend definition syntax (traditionally, at namespace scope), you will have the feature of selectively including headers that make those operators available or not.

这篇关于朋友和内联方法,有什么意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆