c++ 中的友元类/函数

发布于 2024-07-16 23:24:29 字数 282 浏览 6 评论 0原文

可能的重复:
什么时候应该在 C++ 中使用“friend”?

我看到了很多人们推荐一个函数/类成为另一个类的朋友,尽管还有其他选择。 C++ 中是否应该少用友元? 我觉得在决定使用好友功能之前必须考虑其他选择。 欢迎提出意见/建议。

Possible Duplicate:
When should you use 'friend' in C++?

I see a lot of people recommending a function/class to be made a friend of another class here in SO though there are other alternatives. Shouldn't friend be sparingly used in C++? I feel other options must be considered before deciding on using the friend feature. Opinions/suggestions are welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

吾家有女初长成 2024-07-23 23:24:29

有人说 friend 违反了封装性。 在我看来,情况恰恰相反。 如果没有 friend,我们最终会得到:

  • 巨大的整体类,它做了很多他们不打算做的事情,只是为了避免让外部类访问其内部
  • 封装得很差的类:分离关注点并编写如果类具有且仅有一个职责,我们需要提供对相关类集所需的内部数据的公共访问。

friend 是解决这个问题的好方法,因为它可以让您自由地分离多个类中的职责,同时让您将对实现细节的访问限制为需要它们的少数函数或类型。

Some say friend is a violation of encapsulation. In my opinion, it is the exact contrary. Without friend, we would end up with either:

  • huge monolithic classes, that does plenty of things they were not meant to, just to avoid letting outer classes access their internals
  • badly encapsulated classes: to separate concerns and write classes with one and only one responsability, we would need to provide public access to internal data needed by the related set of classes.

friend is a good way to overcome this issue, since it lets you free to separate responsabilities in several classes, while at the same time letting you restrict access to implementation details to the few functions or types which need them.

浸婚纱 2024-07-23 23:24:29

我同意。 应谨慎使用friend 关键字。

如果您有一组可以一起交互的类,当您想要向用户公开这些类的干净 api,但这些类可以使用更丰富的接口相互交互时,这可能会很有用。

例如:

class Folder
{
public:
  int GetFileCount();
private:
  void IncrementFileCount();  // users of this class have no right to use this

  friend class File;
};

class File
{
public:
  File(string name, Folder& containingFolder)
  {
     containingFolder.IncrementFileCount(); // except for indirectly when they create a file
  }
};

I agree. The friend keyword should be used sparingly.

It may be useful if you have a set of classes that interact together when you want to expose a clean api from those classes to users, but when the classes can interact with each other using a richer interface.

Eg:

class Folder
{
public:
  int GetFileCount();
private:
  void IncrementFileCount();  // users of this class have no right to use this

  friend class File;
};

class File
{
public:
  File(string name, Folder& containingFolder)
  {
     containingFolder.IncrementFileCount(); // except for indirectly when they create a file
  }
};
水波映月 2024-07-23 23:24:29

如果没有具体的例子,这很难下定论。 虽然 friend 并不是绝对必要的,但它确实有其用途。 如果,正如您所说,有更好的选择,那么显然可以使用“更好”一词的简单定义它们。 或者也许哪种解决方案更好的决定毕竟不是那么明确。

就我个人而言,我更愿意尽可能避免它,但我更喜欢使用它而不是方法重复:例如,我不喜欢编写 print 方法只是为了避免使 operator << 一个朋友,因为我没有看到重复方法的好处。

Without specific examples this is hard to decide. While friend isn't strictly necessary it does have its uses. If, as you claim, there are better alternatives then obviously use them, by simple definition of the word “better”. Or maybe the decision which solution is better isn't that clean-cut after all.

Personally, I prefer to avoid it when possible but I prefer to use it over method duplication: for example, I do not like to write a print method just to avoid making operator << a friend because I don't see the benefit of the duplicate method.

绿光 2024-07-23 23:24:29

对于所有认为朋友违反封装的人,以下是 Bjarne Stroustup 必须说的

但我个人不会使用朋友,除非不可避免。 像实现 迭代器 模式这样的场景没有其他选择。

朋友如果使用得当就是朋友,否则就是敌人!

For all those who thinks friend violates the encapsulation, here is what Bjarne Stroustup has to say .

But I personally don't use friend unless it is inevitable. Scenarios like implementation of Iterator patterns there is no other choice.

Friend is friend if used properly otherwise he is enemy!

执笏见 2024-07-23 23:24:29

当您想要调用需要访问类成员的第三方库函数时,友元函数非常有用,例如:

class A {
private:
     int x,y;
     double result;
public:
     friend void *power(void *x);
}

You can now call the pow function found in math.h using this friend function.Your power function can now be defined as:


void *power(void *X)
{
     A *a;
     a = static_cast< A *> (X);
     a->result = pow(a->x,a->y);
     return NULL;
}

Although there are easier ways of calling the pow function.This example is only meant to illustrate the importance of friend function in calling library functions.
Hope it is useful.

Friend functions are advantageous in cases where you would want to call a 3rd party library function which needs access to members of your class, consider for example:

class A {
private:
     int x,y;
     double result;
public:
     friend void *power(void *x);
}


You can now call the pow function found in math.h using this friend function.Your power function can now be defined as:


void *power(void *X)
{
     A *a;
     a = static_cast< A *> (X);
     a->result = pow(a->x,a->y);
     return NULL;
}


Although there are easier ways of calling the pow function.This example is only meant to illustrate the importance of friend function in calling library functions.
Hope it is useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文