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

friend声明是否影响基类成员可访问性?附继承场景实例

关于C++友元声明与继承结合的疑惑分析

你遇到的核心问题是Base类的友元无法透过protected继承的Derived对象访问Base子对象的成员,原因得从友元的作用范围和继承的访问控制规则两方面拆解:

示例1(public继承)代码

struct Base
{
    friend int main(); 

public:
    int i;

protected:
    int j;

private:
    int k;
};

struct Derived : public Base
{
public:
    int l;
protected:
    int m;
private:
    int n;
};

int main()
{
    Derived d; 
    d.i = 1;
    d.j = 2;
    d.k = 3;
    d.l = 4;
    d.m = 5; //error
    d.n = 6; //error

    return 0;
}

示例2(protected继承)代码

struct Base
{
    friend int main(); 

public:
    int i;

protected:
    int j;

private:
    int k;
};

struct Derived : protected Base
{
public:
    int l;
protected:
    int m;
private:
    int n;
};

int main()
{
    Derived d; 
    d.i = 1; //error
    d.j = 2; //error
    d.k = 3; //error
    d.l = 4;
    d.m = 5; //error
    d.n = 6; //error

    return 0;
}

关键规则解释

  • 友元的本质:Base声明main()为友元,仅赋予main()直接访问Base类对象所有成员的权限,这个权限不会继承给Derived,也不意味着main()能直接访问Derived的成员。
  • public继承的访问逻辑:public继承时,Derived对象的Base子对象对外部是可见的(可以被当作Base对象处理)。main()访问d.j、d.k时,实际是访问Derived对象中包含的Base子对象的成员,而main()作为Base的友元,自然有权操作这部分内容。
  • protected继承的访问逻辑:protected继承会把Base的所有成员在Derived中变成protected权限,同时外部代码(包括Base的友元)无法直接访问Derived的Base子对象——因为Derived把Base的接口隐藏成了protected,外部只能访问Derived自身的public成员(比如l)。此时main()就算是Base的友元,也没法突破Derived的protected访问限制去碰它内部的Base子对象。
  • 额外说明:两个示例中main()都无法访问m、n是正常的,因为友元关系不能传递,Base的友元不会自动成为Derived的友元。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:07:34