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

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

问题描述

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

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

我不明白为什么将此方法声明为好友.我认为如果该函数在其他位置定义并且需要访问该类的内部成员会很有意义,但是这里不是这种情况,因为它是内联的,甚至不需要访问这些成员. /p>

您怎么看? 朋友"没用吗?

解决方案

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

被称为friend definition.它将函数定义为出现在其周围的类的名称空间的非成员函数.实际上,内联是多余的:如果是朋友定义,则将其隐式声明为内联.它的一些优点和缺点:

  • 它使操作员对常规查找不可见.调用它的唯一方法是使用依赖于参数的查找.这将使命名空间中没有许多正常可见的运算符声明.请注意,这还会禁用使用对MonitorObjectString的隐式转换来调用它的功能(因为如果两种参数类型在查找要调用的候选对象时都不匹配,则依赖于参数的查找将找不到该函数). /li>
  • 对名称的查找始于出现在好友定义中的类的范围.这意味着不需要写长的类型名称或其他名称.只需像在类的普通成员函数中一样引用它们即可.
  • 由于是朋友,因此该函数可以看到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 needs to access the internal member of the class, 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 dependent look-up. This will keep the namespace free of lots of operator declarations visible normally. Note that this will also disable the 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 need 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 - regardless 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天全站免登陆