C++ public/protected/private继承规则及使用疑问
C++类继承可见性相关问题解答
以下是我的理解,恳请各位指正:C++类的继承可见性规则在多层继承场景下十分重要,对吗?
class Base { public : int a; protected : int b; private : int c; }; class Layer_1 : private Base { /* everything from ´Base´ is now */ int z{Base::a}; /* considered a private of ´Layer_1´ */ int r{Base::b}; /* but accessible here */ }; class Layer_2 : Layer_1 { /* Nothing in ´Layer_1´ is accessible from */ int y{Layer_1::a}; /* ´Layer_2´,as ´Layer_1´ inherited everything */ }; // invalid ~~~~^ /* from ´Base´ into their private scope */
问题与解答
- 这些继承可见性规则还有其他用途吗?
- 当然有。除了控制多层继承的访问权限,它还能实现接口隔离:比如用private继承可以把基类的接口隐藏,只暴露子类自己定义的接口,避免外部误调用基类方法;
- 还能辅助实现实现复用:比如private/protected继承基类,只是为了复用基类的代码逻辑,但不想让外部感知到基类的存在;
- 另外,protected继承可以让子类的子类也能访问基类的成员,适合构建类族的共享逻辑。
- 必须谨慎使用,因为一旦以protected方式继承类后,无法再改为public等,该说法是否正确?
- 这个说法是对的。继承方式是子类定义时就固定的,一旦确定为protected继承,后续子类(比如Layer_2继承Layer_1)无法改变Layer_1对Base的继承可见性。也就是说,Layer_1把Base的成员变成protected后,Layer_2只能看到这些protected成员,没法把它们再改成public暴露给外部。
- 若仅存在Base和Layer两个类,由于不会再继承Layer,那么以何种方式继承Base其实无关紧要,对吗?
- 不完全对。即使没有后续继承,不同的继承方式对外部访问权限还是有影响:
- public继承:外部可以通过Layer对象直接访问Base的public成员(比如
Layer obj; obj.a;是合法的); - protected/private继承:外部无法访问Base的任何成员,哪怕是public的a,外部通过Layer对象访问会报错;
- public继承:外部可以通过Layer对象直接访问Base的public成员(比如
- 另外,private继承下,Layer内部虽然能访问Base的public/protected成员,但这些成员在Layer里是private的,哪怕未来突然要继承Layer,也没法用,不过如果确定永远不会继承,这一点可以忽略,但外部访问的差异还是存在的。
- 关于public/protected/private继承的使用时机和方式,是否有公认的惯例或行业标准,还是需根据具体情况决定,并无固定规则?
- 有公认的惯例:
- public继承:最常用,代表"is-a"关系(比如
class Dog : public Animal,狗是一种动物),此时基类的接口完全暴露给外部,符合面向对象的多态设计; - protected继承:用于构建类族内部的共享逻辑,代表"is-implemented-in-terms-of"的变种,只有子类和子类的子类能访问基类成员,外部看不到;
- private继承:代表"is-implemented-in-terms-of"(实现上依赖基类),只是为了复用基类的代码,外部完全感知不到基类的存在,相当于把基类当成子类的内部实现细节;
- public继承:最常用,代表"is-a"关系(比如
- 当然具体场景还是要灵活调整,但这些惯例是行业内普遍遵循的,能让代码更易读,符合其他开发者的预期。
内容的提问来源于stack exchange,提问作者LLL
相关产品推荐
相关产品推荐

