【问题标题】:Can a member function (as opposed to the entire class) befriend a function/class?成员函数(而不是整个类)可以与函数/类交朋友吗?
【发布时间】:2016-02-07 15:48:26
【问题描述】:

函数 F 可以声明为类 C 的友元,以便它可以访问整个类的私有成员和受保护成员。

但是有没有办法只允许 F 访问 C 的特定成员函数,而不是允许 F 访问整个类?

This 是我想要这样做的原因。

【问题讨论】:

    标签: c++ friend


    【解决方案1】:

    不,你不能。

    一种解决方法是将特定的成员函数放在一个单独的类 C2 中,C 从该类继承,并建立与 C2 的友谊。

    【讨论】:

    • 或者 C2 可以为 C 中的某些内容提供包装接口,因此您不必设置人为的继承层次结构。
    【解决方案2】:

    没有办法直接用友谊做到这一点,但你可以通过修改基于标签的调度来达到类似的效果:

    class C
    {
    public:
      class AccessTag
      {
        friend class C;
        friend void F();
      private:
        AccessTag() {}
      };
    
      void functionToAccess(AccessTag)
      {
        std::cout << "Restricted function called!\n";
      }
    };
    
    void F()
    {
      C c;
      c.functionToAccess(C::AccessTag()); // OK
    }
    
    void nonF()
    {
      C c;
      c.functionToAccess(C::AccessTag()); // error, nonF cannot access ctor of C::AccesTag
    }
    

    这个想法是只允许那些可以构造C::AccessTag 对象的人调用functionToAccess。而且由于它的私有构造函数,C::AccessTag 只能由它的朋友构造。它们是C(这样它就可以调用functionToAccess 本身,就像它可以调用它的任何其他私有函数一样)和FF 不能访问C 的任何其他非公开成员,因为它不是C 的朋友。

    您甚至可以为不同的成员函数(或成员函数组)设置不同的访问标签。

    【讨论】:

    • 在此示例中,您不需要 C 成为朋友,因为它不会自行创建 AccessTag。如果需要,它甚至可以复制标签对象,因为复制操作在AccessTag 中是隐式公开的。此外,您还可以将AccessTag 设为C 的(公共)成员类,因为它并不是真正的独立实体,而是属于C
    • @ArneMertz 我将C 添加为好友只是为了保持默认行为“类可以调用其私有函数”。但是关于使它成为一个嵌套类的好处,将会修改。
    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 2021-08-16
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    相关资源
    最近更新 更多