明确调用父类函数需用作用域解析符::,它绕过虚函数机制强制静态绑定;若要引入父类重载函数则需using声明。

直接用 :: 调用父类函数,不触发虚函数机制
当你在子类成员函数里想明确执行父类的某个实现(哪怕该函数是虚函数),就得用作用域解析运算符 ::。它绕过动态绑定,强制调用指定类版本的函数。
常见错误是以为写了 Base::func() 就自动“继承行为”,其实这只是显式调用——如果父类函数没定义、或访问权限不够(比如 private),编译直接报错。
-
Base::func()只能在派生类内部或友元中使用;外部代码不能这么写 - 若父类函数是
virtual,但你用了Base::func(),那运行时不会查虚表,一定执行Base的版本 - 多重继承时,必须写全路径,如
Parent1::func()或Parent2::func(),否则可能歧义
构造函数里调用父类构造函数只能在初始化列表
子类构造函数不能在函数体里用 Base::Base(...) 去调父类构造函数——语法非法,编译器会报 error: constructor delegation only allowed in constructor 或类似提示。
正确方式只有一种:在初始化列表中写 : Base(arg)。
立即学习“C++免费学习笔记(深入)”;
- 初始化列表中的
Base(...)是调用,不是普通函数调用,不能带返回值、不能放 if 里、不能重复出现 - 如果父类没有默认构造函数,子类构造函数必须显式写初始化列表,否则编译失败
- 多个基类时,顺序按继承声明顺序走,不是按初始化列表书写顺序
虚函数重写后,仍想复用父类逻辑怎么办
典型场景:子类重写了 virtual void draw(),但希望先做父类的通用绘制,再加自己的特效。这时就要在子类 draw() 里手动调 Base::draw()。
注意这不是“自动继承”,而是你主动插入的一次普通函数调用。
void Derived::draw() {
Base::draw(); // 显式复用父类逻辑
render_effect(); // 自己的额外操作
}
- 别漏掉
Base::,否则会无限递归(如果没写,就又调自己) - 如果父类函数是
protected或public,才能这么调;private成员函数子类根本不可见 - 这种写法和多态不冲突:对象仍是
Derived*,但你主动切到了Base的实现上下文
用 using 声明把父类重载函数带进来
子类定义了同名函数后,会隐藏父类所有同名重载版本(哪怕参数不同)。这时候想保留父类的某些重载,得用 using Base::func; 显式引入。
否则会出现“明明父类有 func(int),但子类对象调 obj.func(42) 却报错”的情况。
-
using声明必须写在子类定义体内,通常放在public:下 - 它只是让名字可见,不改变访问权限;如果父类函数是
private,using也无效 - 多个重载要全部带进来,不能只挑一个参数类型的;
using是按函数名批量导入
::,想带入重载就用 using。多态本身不帮你自动转发,一切取决于你写没写那行 Base::。最容易忽略的是构造函数初始化列表的强制性,以及 private 成员根本不可见这两点。










