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
相关产品推荐
相关产品推荐

