在C++的继承机制中,名字隐藏和重写(override)是两个容易混淆但本质不同的概念。理解它们的区别对正确使用多态和继承至关重要。
名字隐藏(Name Hiding)当派生类中定义了一个与基类同名的函数(无论参数列表是否相同)或变量,基类中的同名成员将被隐藏,即使函数签名不同。
这种隐藏不依赖于函数的参数列表,也不要求是虚函数。
- 隐藏发生在编译期,属于静态行为
- 只要派生类有同名函数,基类所有同名函数都会被隐藏(即使参数不同)
- 即使基类函数是虚函数,也会被隐藏(除非被正确重写)
示例:
class Base { public: void func() { cout << "Base::func()" << endl; } void func(int x) { cout << "Base::func(int)" << endl; } }; <p>class Derived : public Base { public: void func(double x) { cout << "Derived::func(double)" << endl; } };</p><p>// 调用 Derived d; d.func(); // 错误!Base::func() 被隐藏,无法直接调用 d.func(1); // 错误!Base::func(int) 也被隐藏 d.func(3.14); // OK,调用 Derived::func(double)</p>
要恢复基类函数的可见性,可以使用 using 声明:
class Derived : public Base { public: using Base::func; // 引入基类所有 func 重载 void func(double x) { cout << "Derived::func(double)" << endl; } };重写(Override)
重写是指派生类中提供一个与基类虚函数具有相同签名的函数,实现多态。
重写发生在运行时,通过虚函数表实现动态绑定。
- 必须是虚函数(基类函数用 virtual 声明)
- 函数签名必须完全一致(返回类型、参数列表、const 修饰等)
- 发生在运行期,支持多态调用
- 使用 override 关键字可显式声明,帮助编译器检查错误
示例:
class Base { public: virtual void show() { cout << "Base::show()" << endl; } }; <p>class Derived : public Base { public: void show() override { cout << "Derived::show()" << endl; } // 正确重写 };</p>
调用时体现多态:
Base* ptr = new Derived(); ptr->show(); // 输出 "Derived::show()",动态绑定关键区别总结
- 发生时机:名字隐藏在编译期,重写在运行期
- 是否需要 virtual:重写必须基于虚函数,隐藏不需要
- 函数签名:重写要求完全一致,隐藏只要同名即可
- 多态支持:只有重写支持动态多态
- 作用范围:隐藏会屏蔽基类所有同名重载,重写只影响一个函数
简单说:隐藏是名字层面的覆盖,重写是接口层面的多态实现。
使用 override 关键字能有效避免误写成隐藏而本意是重写的问题。
基本上就这些。
以上就是C++继承中的隐藏 名字隐藏与重写区别的详细内容,更多请关注知识资源分享宝库其它相关文章!
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。