子类同名函数会隐藏父类所有同名函数,无论参数或虚函数属性,且不形成重载,仅通过子类对象调用时父类版本不可见。

在C++中,隐藏父类方法是指子类中定义了一个与父类同名的函数,导致父类中的该函数在子类中不可见。这不同于重写(override),因为隐藏不依赖于虚函数机制,只要名字相同就可能发生。
1. 函数名相同即触发隐藏
当子类中声明了一个与父类同名的函数,无论参数列表是否相同、是否为虚函数,都会隐藏父类中所有同名函数。
- 即使参数不同,也不会形成重载关系(在子类作用域内)
- 父类的多个重载版本都会被隐藏
示例:
```cpp class Base { public: void func() { cout class Derived : public Base { public: void func(double x) { cout// 调用时: Derived d; d.func(3.14); // OK: 调用 Derived::func(double) d.func(); // 错误!Base::func() 被隐藏,无法直接调用 d.Base::func(); // OK: 显式通过作用域访问
2. 使用 using 恢复父类方法
如果希望在子类中保留父类的重载版本,可以使用 using 声明 将父类函数引入子类作用域。
立即学习“C++免费学习笔记(深入)”;
解决方法:
```cpp class Derived : public Base { public: using Base::func; // 引入Base中所有func,恢复重载 void func(double x) { cout << "Derived::func(double)" << endl; } }; // 现在可以正常调用: Derived d; d.func(); // OK: 调用 Base::func() d.func(10); // OK: 调用 Base::func(int) d.func(3.14); // OK: 调用 Derived::func(double)
3. 虚函数与隐藏的区别
注意区分“隐藏”和“重写”:
- 隐藏:函数名相同,但签名或是否为虚函数不影响,静态绑定
- 重写:虚函数 + 相同签名 + 子类覆盖,动态绑定
- 若父类是虚函数,子类同名函数会自动重写(除非签名不同,则变成隐藏)
示例:
```cpp class Base { public: virtual void show() { cout class Derived : public Base { public: void show(int x) { cout// 调用: Derived d; Base* b = &d; b->show(); // 调用 Base::show(),因为 Derived::show(int) 不匹配
4. 实用技巧总结
避免意外隐藏的建议:
- 子类中若需扩展同名函数,优先考虑是否应重写虚函数
- 如需保留父类重载,显式使用 using Base::func;
- 命名时避免无意覆盖,尤其是公共接口
- 使用 override 关键字明确意图,防止拼写错误导致隐藏
基本上就这些。掌握隐藏机制有助于写出更清晰、可维护的继承代码。关键是理解作用域查找规则:子类名字一旦匹配,就停止向上查找。









