protected继承下外部代码不能进行d→b转换,仅派生类及其后代类内部可转换;其本质是隐式转换操作被设为protected访问级别,而非成员可见性问题。

protected 继承下,外部代码不能做 D → B 转换
不能。只要继承方式是 protected,任何在类外部(比如 main()、普通函数、非友元类成员)尝试把派生类对象当基类来用的操作,都会编译失败。
典型错误包括:
-
Base& b = derived_obj;→ 报错:'Base' is an inaccessible base of 'Derived' -
Base* p = &derived_obj;→ 同样报错 - 传
Derived对象给接受Base&或Base*的函数 → 编译不通过
这不是语法限制,而是访问控制规则:protected 继承把“派生类到基类的隐式转换”设为 protected 访问级别,外部不可见。
protected 继承下,派生类内部和后代类仍可转换
只要在 Derived 类内部或它的友元中,或者在从 Derived 再派生出的类(孙类)里,就能合法使用 Derived → Base 转换。
例如:
class Base { public: void foo() {} };
class Derived : protected Base {
public:
void inDerived() {
Base& b = *this; // ✅ OK:类内部允许
b.foo();
}
};
class GrandChild : public Derived {
public:
void inGrandChild() {
Base& b = *this; // ✅ OK:protected 继承允许后代类访问转换
}
};
注意:GrandChild 必须以 public 或 protected 方式继承 Derived 才能继续访问;若用 private 继承,则连孙类也失去该能力。
为什么 protected 继承几乎没人用
它语义模糊,既不像 public 那样明确表达“is-a”,也不像 private 那样彻底隐藏实现细节。
- 想对外暴露基类接口?→ 用
public继承 - 只想复用基类实现,完全不想让用户感知基类存在?→ 用
private继承或组合(Engine e_;)更清晰 - 想让孙类能访问基类但又不让用户代码用?→ 理论上可行,但实际工程中极少有这种强约束需求
多数团队直接禁用 protected 继承,避免理解成本和误用风险。
替代方案:用 using 声明局部提升访问权限
如果你真需要某几个基类成员在派生类外部可用,又不想改成 public 继承,可以用 using 显式声明:
class Derived : protected Base {
public:
using Base::foo; // ✅ 外部 now can call derived.foo()
using Base::bar; // 同理
};
但这只开放指定成员,不开放隐式转换本身。也就是说:derived.foo() 可行,但 Base& b = derived; 依然不行。
真正容易被忽略的是:protected 继承的“可转换性”不是靠成员访问权限控制的,而是由转换操作本身的访问属性决定的——它独立于 public/protected/private 成员的可见性,属于语言层面的转换规则。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











