1

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

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

4

5 回答 5

10

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

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

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

于 2009-04-09T13:02:08.430 回答
4

我同意。应谨慎使用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
  }
};
于 2009-04-09T13:00:06.093 回答
3

如果没有具体的例子,这很难决定。虽然friend不是绝对必要的,但它确实有它的用途。如果,正如您所声称的,有更好的选择,那么显然使用它们,通过“更好”这个词的简单定义。或者,也许哪个解决方案更好的决定毕竟不是那么干净利落。

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

于 2009-04-09T12:58:02.230 回答
1

对于所有认为朋友违反封装的人,这里是 Bjarne Stroustup 不得不的。

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

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

于 2009-04-09T13:02:12.407 回答
0

在您想要调用需要访问您的类成员的第 3 方库函数的情况下,Friend 函数是有利的,例如:

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

您现在可以使用这个友元函数调用在 math.h 中找到的 pow 函数。您的幂函数现在可以定义为:

void *power(void *X)
{
     A *a;
     a = static_cast< A *> (X);
     a->result = pow(a->x,a->y);
     return NULL;
}
虽然调用 pow 函数有更简单的方法。这个例子只是为了说明友元函数在调用库函数中的重要性。希望它是有用的。

于 2009-08-24T13:11:29.747 回答