非会员功能如何改善封装 [英] How Non-Member Functions Improve Encapsulation

查看:102
本文介绍了非会员功能如何改善封装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了Scott Meyers关于这个主题的文章,对他所谈论的内容很困惑。我在这里有3个问题。



问题1



详细解释,假设我正在写一个简单的向量类使用 push_back insert 和运算符 [] 。如果我遵循mayers算法,我将最终与所有非成员朋友的功能。我将有一个向量类,只有很少的私有成员和许多非成员的朋友函数。这是他在说什么吗?



问题2



不理解非成员函数如何改进封装。考虑meyers文章中给出的代码。

  class Point {
public:
int getXValue ;
int getYValue()const;
void setXValue(int newXValue);
void setYValue(int newYValue);

private:
... // whatever ...
};

如果按照他的算法, setXXXX 应为非成员。我的问题是如何增加封装?他还说


我们现在已经看到一个合理的方式
来衡量封装的数量
类是计数
函数的数量,如果
类的实现发生变化,它们可能会被破坏。


当类实现改变时,我们保持方法签名完整,没有客户端代码会破坏,它被很好地封装,对吗?这同样适用于非成员函数。非成员函数提供的优势是什么?



问题3



引用其算法

  else if(f需要类型转换
在其最左边的参数)
{
make fa非成员函数;
if(f需要访​​问非公共
的C成员)
make f是C的朋友;
}

他的意思是 f需要类型转换参数
他还在文章中说了以下内容。


此外,我们现在看到
common声称朋友函数
违反封装不完全是
true。朋友不违反
封装,他们只是减少它 -
与成员
函数完全相同的方式。


这和上述算法是矛盾的,对吗?

解决方案

问题1



在这种情况下,以下Meyers的算法将会给您以下成员函数:




  • 他们需要是虚拟的吗?

  • 需要类型转换吗?

  • 是否可以根据公开介面执行?



他的建议是只让他们成为朋友他们真的需要;

p> SetXXXX 函数需要访问类的内部(私有)表示,因此它们不能是非成员非朋友;所以,迈尔斯认为,他们应该是成员而不是朋友。



封装是通过隐藏类的实现细节来实现的;您定义了一个与私有实现分开的公共接口。如果你发明一个更好的实现,你可以改变它,而不改变公共接口,任何使用该类的代码将继续工作。所以Meyers的可能被破坏的函数的数量计数成员和朋友函数(我们可以通过查看类定义容易地追踪),但不是通过其公共接口使用该类的任何非成员非朋友函数。



问题3



已回答



重要事项从迈尔斯的建议中去除:




  • 设计类,以使其具有干净,稳定的公共接口与其私有实现分离;

  • 只有在功能成员或朋友确实需要访问实施时才能使用;

  • 只有在成员无法成为朋友时才能使用。


I read Scott Meyers article on the subject and quite confused about what he is talking about. I have 3 questions here.

Question 1

To explain in detail, assume I am writing a simple vector<T> class with methods like push_back, insert and operator []. If I follow mayers algorithm, I would end up with all non-member friend functions. I will have a vector class with few private members and many non-member friend functions. Is this what he is talking about?

Question 2

I am still not understanding how non-member functions improve encapsulation. Consider the code given in meyers article.

class Point {
public:
   int getXValue() const; 
   int getYValue() const; 
   void setXValue(int newXValue);
   void setYValue(int newYValue);

private:
  ...                 // whatever...
};

If his algorithm is followed, setXXXX methods should be non-member. My question is how that increases encapsulation? He also says

We've now seen that a reasonable way to gauge the amount of encapsulation in a class is to count the number of functions that might be broken if the class's implementation changes.

Until we keep the method signature intact when class implementation changes, no client code is gonna break and it is well encapsulated, right? The same applies for non-member functions as well. So what is the advantage non-member function provides?

Question 3

Quoting his algorithm

else if (f needs type conversions
         on its left-most argument)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }

What he meant by f needs type conversions on its left-most argument? He also says the following in the article.

Furthermore, we now see that the common claim that "friend functions violate encapsulation" is not quite true. Friends don't violate encapsulation, they just decrease it — in exactly the same manner as member functions.

This and the above algorithm are contradictory, right?

解决方案

Question 1

In this case, following Meyers's algorithm will give you member functions:

  • Do they need to be virtual? No.
  • Are they operator<< or operator>>? No.
  • Do they need type conversions? No.
  • Can they be implemented in terms of the public interface? No.
  • So make them members.

His advice is to only make them friends when they really need to be; to favour non-member non-friends over members over friends.

Question 2

The SetXXXX functions need to access the internal (private) representation of the class, so they can't be non-member non-friends; so, Meyers argues, they should be members rather than friends.

The encapsulation comes about by hiding the details of how the class is implemented; you define a public interface separately from a private implementation. If you then invent a better implementation, you can change it without changing the public interface, and any code using the class will continue to work. So Meyers's "number of functions which might be broken" counts the member and friend functions (which we can easily track down by looking at the class definition), but not any non-member non-friend functions using the class through its public interface.

Question 3

This has been answered.

The important points to take away from Meyers's advice are:

  • Design classes to have clean, stable public interfaces separate from their private implementation;
  • Only make functions members or friends when they really need to access the implementation;
  • Only make functions friends when they can't be members.

这篇关于非会员功能如何改善封装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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