可以,但仅允许放宽权限:public→public/protected、protected→protected/public;private虚函数不可被派生类访问或重写,因基类private成员在派生类中不可见。

可以改,但只能放宽,不能收紧;基类 public 虚函数不能在派生类中重写为 private,否则编译失败。
哪些权限变更合法?
虚函数重写时的访问权限调整必须满足“可访问性不降级”原则:
-
public→public或protected(允许) -
protected→protected或public(允许) -
private→ 无法被派生类访问,因此根本不能被重写(编译报错:‘Base::f’ is inaccessible)
注意:private 虚函数本身存在,但派生类连声明它的资格都没有——不是“能不能重写”,而是“根本看不见”。
为什么 public 虚函数重写成 private 会失败?
这不是多态机制的问题,而是访问控制的硬性限制。编译器在解析派生类定义时,会检查基类成员是否可访问:
- 若基类函数是
public virtual void f(),派生类写private void f() override,编译器直接拒绝:权限收紧违反继承契约 - 错误信息典型为:
cannot declare member function 'Derived::f' to have private access because it overrides a member function that has public access - 这种限制发生在编译期,和虚表、运行时绑定完全无关
override 关键字对权限检查无影响
override 只校验函数签名(参数、const、返回类型协变等),不参与访问权限判定:
- 即使你加了
override,也不能绕过权限收紧的编译错误 - 反过来,如果权限放宽但签名写错(比如漏了
const),override会立刻报错,帮你避免静默重载 - 所以建议所有重写函数都加
override,哪怕权限没变——它防的是签名错,不是权限错
容易忽略的继承方式干扰
权限问题常被继承方式放大:
- 若用
protected或private继承基类,即使基类虚函数是public,也会在派生类作用域内降级为protected或private - 此时你在派生类里再试图用
public重写,实际是在重写一个已降级的函数,可能触发意外交互 - 查这类问题,先确认
sizeof(Derived)是否包含虚表指针,再用gdb查vtable条目,比猜权限更可靠
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











