26

我正在将代码从 Java 移植到 c++,并且我想复制一些匿名功能。

在文件啊我有:

class A
{
private:
  int a;

  class AnonClass;
  friend class AnonClass;
};

在文件 A.cpp 我有:

namespace
{
  class AnonClass
  {
  public:
    AnonClass(A* parent)
    {
      parent->a = 0; // This doesn't work, a is not accessible
    }
  }
}

是否可以在 C++ 中的匿名命名空间中为类添加好友?

在 Java 中,您可以声明匿名类,因此它会非常相似。它也不会将 AnonClass 暴露给 Ah 的客户

4

2 回答 2

28

鲜为人知的替代方法是让 Anon 类成为 A 的成员类。在 A 类中,您只需要一行class Anon;——没有真正的代码,没有朋友声明。请注意,它属于 A 类,几乎与 Java 中一样。在 .cpp 文件中,您编写了有关 Anon 的所有详细信息,但您不是将其放在匿名命名空间中,而是放在A::

  class A::Anon { ..... };

您可以像往常一样拆分 A::Anon 的声明和实现,只需记住始终将 A:: 添加到 Anon。

Anon 类是 A 的成员,因此可以访问 A 的所有其他成员。然而,A 的客户仍然不知道它,并且不会弄乱全局命名空间。

于 2013-11-09T08:21:27.580 回答
5

据我所知,你不能。原因:

  1. “匿名”命名空间只能在您创建它的文件中访问。
  2. 您必须在一个命名空间中定义整个 AnonClass 类及其功能,即在程序中的一个位置。
  3. A 类必须在 AnonClass 构造函数之前定义。
  4. AnonClass 必须至少在 A 类之前声明。

所以你看,你不能在两个部分上破坏 AnonClass 的定义。而且你不能在 A 类之前和之后都定义它。

唯一的选择 - 将 A 类放入同一个匿名命名空间。此代码有效:

namespace 
{
  class A
  {
   public:
    A():a(0){};
   private:
    int a;

    friend class AnonClass;
  };

  class AnonClass
  {
  public:
    AnonClass(A* parent);
  };

  AnonClass::AnonClass(A* parent)
  {
      parent->a = 0;
  };
}

int main() {
  A a;

  return 0;
}

我希望这有帮助。

于 2013-11-09T07:02:14.960 回答