【问题标题】:How to befriend private nested class如何与私有嵌套类成为朋友
【发布时间】:2019-11-18 21:44:38
【问题描述】:

我认为我可以这样做:

class TestA
{
private:
  class Nested
  {

  };
};

class TestB
{
public:
  friend class TestA;
  friend class TestA::Nested;
};

但我得到一个错误:

错误 C2248 'TestA::Nested': 无法访问类中声明的私有类

有没有办法让私有嵌套类成为朋友?我该怎么做?

我在尝试在 MSVC 2017 (C++17) 中编译 MSVC 6 项目时遇到此错误。我想它当时有效。

【问题讨论】:

  • @TarickWelling No. TestB 并非源自TestA
  • TestA 需要将TestB 声明为friendTestB 不能使用 TestA::Nested,除非 TestA 允许。
  • TestA 也应该是朋友,还是只是 Nested

标签: c++ c++17 friend


【解决方案1】:

与您访问任何其他私人事物的方式相同。你需要另一种友谊:

class TestA
{
  friend class TestB; // <== this
private:
  class Nested
  {

  };
};

class TestB
{
public:
  friend class TestA;
  friend class TestA::Nested; // <== now we're a friend of TestA, so we can access it
};

【讨论】:

  • @Quentin 我是说巴里找到了structural 的生活方式while 维护class。这就是为什么我渴望成为friend
  • @SombreroChicken 如果没有int main(),您将无法拼写maintaining
【解决方案2】:

这样就可以了:

class TestA {
   friend class TestB;
   private:

   class Nested {};
};

class TestB {
   public:
      friend class TestA::Nested;
};

解释:TestA 本身有责任将访问其内部的权限提供给其他人。想象一下任何class 可以侵入性地使用友谊来访问其他类的内部(从库等),这将打开任意破坏封装的大门。

【讨论】:

  • @Bathsheba 感谢您让我的回答更加自信;)
  • 如何授予友谊给一个无法访问的类打破封装?更可能的问题似乎是重命名/删除私有类的脆弱性。
  • @DavisHerring 重命名/删除确实是另一个问题,好点。我的意思是,如果某些客户端代码能够将自己置于与另一个类的friend 关系中,可能在它自己的代码库之外,那么这确实会破坏封装。
【解决方案3】:

您尝试在TestB 中使用TestAprivate 嵌套类,那么您应该在TestA 中将TestB 声明为friend。例如

class TestA
{
private:
  class Nested
  {

  };
  friend class TestB; // allow TestB to access the private members of TestA
};

【讨论】:

    【解决方案4】:

    只需注释掉friend class TestA::Nested; 行如下:

    class TestA
    {
    private:
      class Nested
      {
    
      };
    };
    
    class TestB
    {
    public:
      friend class TestA;
      // friend class TestA::Nested;
    };
    

    由于TestA::Nested 的作用域与TestA 相似,因此TestA::Nested 的方法可以访问TestB 的私有/受保护成员。

    【讨论】:

    • 我想知道投票者是否真的对此进行了测试。这个答案是 100% 正确的godbolt.org/z/VypZo2
    • @sebrockm - 您是否错过了它不允许访问 Nested 的事实?它没有正确回答问题。或者,无论其相关性如何,您都会对每段代码进行投票?
    • @StoryTeller 请帮我找出问题中想要访问Nested 的部分。如果我的英语没有太大的缺陷,OP 想要让 TestA::Nested 访问 TestB 的私有字段(又名让 Nested 成为 TestB 的朋友)。这个答案说“通过让TestA 成为朋友,Nested 也将自动成为朋友。”那么这个答案有什么问题呢?
    • @sebrockm - Nested 也不是朋友,它使用 TestA 的友谊和范围规则。这可能会或可能不会被接受。但是,它并没有回答如何与Nested 成为朋友的问题。 OP 似乎希望它尽管能够与TestA 成为朋友。因此,人们有权认为这个答案对这个问题没有用处。 100% 正确与否。
    • @StoryTeller 是否对某些命名(是否称为友谊)产生分歧,尽管它完全相同,是否有理由反对,可能是讨论的主题。然而,我宁愿相信投票者只是不相信这是有效的,没有测试它,误解了谁应该访问谁(就像你刚刚发生的那样)。
    猜你喜欢
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2014-06-18
    • 1970-01-01
    • 2011-03-18
    • 2016-12-27
    相关资源
    最近更新 更多