You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Other::second_function()访问HavePrivateMember的私有成员set_member

问题描述

需要让Other::second_function()能够访问HavePrivateMember类的私有成员函数set_member,原始代码如下:

class HavePrivateMember {
private:
  int _m_member;
  void set_member(int val) { _m_member = val; }
};

class OtherBase {
};
class Other : public OtherBase {
   virtual void first_function(); // 无访问权限
   virtual void second_function(); // 需访问HavePrivateMember::set_member
};

尝试在Other::second_function()内定义嵌套类PenetratingClass并将其声明为HavePrivateMember的友元,但运行报错:

class HavePrivateMember {
friend class PenetratingClass;
private:
  int _m_member;
  void set_member(int val) { _m_member = val; }
};

class Other : public OtherBase {

   virtual void second_function() {
      HavePrivateMember has_private_obj;

       class PenetratingClass {
         public:
          void penetrate(HavePrivateMember& has_private_obj) {
             has_private_obj.set_member(5);
          }
       };
       PenetratingClass my_penet;
       my_penet.penetrate(has_private_obj);
   }
};

报错信息:

error: void HavePrivateMember::set_member(int) is private
错误原因

你之前的方案失效是因为函数内部定义的局部类PenetratingClass,和HavePrivateMember里声明友元的PenetratingClass不是同一个类。友元声明里的PenetratingClass是全局命名空间下的类,而你在second_function里定义的是函数作用域内的局部类,两者毫无关系,自然无法获得访问权限。

正确实现方案

方案一:将穿透类放在Other的类作用域下

把PenetratingClass定义在Other类内部(而非函数内),然后在HavePrivateMember里明确声明这个嵌套类为友元:

// 前置声明Other类,因为HavePrivateMember需要引用它的嵌套类
class Other;

class HavePrivateMember {
    // 明确声明Other的嵌套类为友元
    friend class Other::PenetratingClass;
private:
    int _m_member;
    void set_member(int val) { _m_member = val; }
};

class OtherBase {
};

class Other : public OtherBase {
public:
    // 在Other类作用域下定义穿透类
    class PenetratingClass {
    public:
        void penetrate(HavePrivateMember& obj) {
            obj.set_member(5);
        }
    };

    virtual void first_function();
    virtual void second_function() {
        HavePrivateMember has_private_obj;
        PenetratingClass my_penet;
        my_penet.penetrate(has_private_obj);
    }
};

方案二:直接让Other::second_function成为友元

如果不需要额外的穿透类,可以直接把Other的second_function声明为HavePrivateMember的友元,注意前置声明的顺序:

// 前置声明Other类
class Other;

class HavePrivateMember {
    // 直接声明Other的成员函数为友元
    friend void Other::second_function();
private:
    int _m_member;
    void set_member(int val) { _m_member = val; }
};

class OtherBase {
};

class Other : public OtherBase {
public:
    virtual void first_function();
    virtual void second_function() {
        HavePrivateMember has_private_obj;
        has_private_obj.set_member(5); // 直接访问私有成员函数
    }
};
补充说明
  • 方案一的优势是能把访问私有成员的逻辑封装在穿透类中,避免second_function直接操作私有成员,更符合封装原则。
  • 方案二更简洁,适合仅second_function需要访问私有成员的场景。

内容的提问来源于stack exchange,提问作者bochaltura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:27:19