是否可以在 C++ 中将未命名命名空间中的类添加为友元?

问题描述 投票:0回答:2

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

在文件 A.h 中我有:

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 暴露给 A.h

的客户
c++ namespaces friend unnamed-namespace
2个回答
29
投票

鲜为人知的替代方案是使 Anon 类成为 A 的成员类。在 A 类中,您只需要一行

class Anon;
—— 没有真正的代码,没有友元声明。请注意,它位于 A 类中,几乎与 Java 中一样。在 .cpp 文件中,您编写有关 Anon 的所有详细信息,但您没有将其放在匿名名称空间中,而是放在
A::

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

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

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


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;
}

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.