理解重写(Overriding)、重载(Overloading)以及隐藏(Hiding)之间的关系和区别是很重要的。以下是一个简单的C++示例代码,帮助解释它们的概念:
#include <iostream>
using namespace std;// 基类 Base
class Base {
public:// 基类的普通函数,可以被隐藏或重载void display() {cout << "Base::display() called" << endl;}// 虚函数可以被重写(Overridden),但不能被重载(Overloaded)或隐藏(Hidden)virtual void show() {cout << "Base::show() called" << endl;}// 静态函数,不能被重写static void print() {cout << "Base::print() called" << endl;}
};// 派生类 Derived
class Derived : public Base {
public:// 子类中的同名函数,隐藏基类的同名函数void display() {cout << "Derived::display() called" << endl;}// 重写基类的虚函数void show() override {cout << "Derived::show() called" << endl;}// 重载show函数,与基类的虚函数无关void show(int num) {cout << "Derived::show(int) called with " << num << endl;}// 静态函数,与基类的静态函数无关,隐藏无意义static void print() {cout << "Derived::print() called" << endl;}
};int main() {Base b;Derived d;// 隐藏示例b.display(); // 输出 Base::display() calledd.display(); // 输出 Derived::display() called// 重写和多态示例b.show(); // 输出 Base::show() calledd.show(); // 输出 Derived::show() called// 重载示例d.show(5); // 输出 Derived::show(int) called with 5// 静态函数示例Base::print(); // 输出 Base::print() calledDerived::print(); // 输出 Derived::print() calledreturn 0;
}
代码解释
-
隐藏(Hiding):
- 在派生类中定义与基类同名的非虚函数或静态函数时,派生类的函数会隐藏基类中的同名函数。在示例中,
Derived::display()
和Derived::print()
分别隐藏了Base::display()
和Base::print()
。
- 在派生类中定义与基类同名的非虚函数或静态函数时,派生类的函数会隐藏基类中的同名函数。在示例中,
-
重写(Overriding):
- 在派生类中重新定义基类的虚函数,这样可以在运行时动态调用派生类的实现。在示例中,
Derived::show()
重写了Base::show()
,允许通过基类指针或引用调用时产生多态效果。
- 在派生类中重新定义基类的虚函数,这样可以在运行时动态调用派生类的实现。在示例中,
-
重载(Overloading):
- 在同一个作用域内,定义多个同名函数但参数列表不同,称为重载。重载的函数可以是虚函数、非虚函数或静态函数。在示例中,
Derived::show(int num)
重载了Derived::show()
,这两个函数在参数列表上有所区别。
- 在同一个作用域内,定义多个同名函数但参数列表不同,称为重载。重载的函数可以是虚函数、非虚函数或静态函数。在示例中,
总结
- 隐藏(Hiding):子类中的同名函数会隐藏父类中的同名函数,无论是虚函数、非虚函数还是静态函数。
- 重写(Overriding):子类可以重新定义父类的虚函数,允许在运行时动态调用子类的实现,实现多态性。
- 重载(Overloading):在同一作用域中,可以定义多个同名函数但参数列表不同的函数,用来处理不同的参数类型或数量。
静态函数相关:
-
静态函数不受重写影响:
- 静态函数在类的继承中不会被重写。无论在基类中如何定义静态函数,在派生类中重新定义同名的静态函数,不会形成重写关系。实际上,它们只是同名函数而已,没有多态性的特性。
-
静态函数与隐藏:
- 静态函数在类的继承中也不能被隐藏。如果在派生类中定义了与基类同名的静态函数,它们不会相互隐藏,而是分别存在于各自的作用域中。这与非静态函数的隐藏行为不同。
-
静态函数的调用:
- 静态函数可以通过类名直接调用,不需要对象的实例。这使得静态函数在面向对象编程中常用于不需要依赖于特定对象状态的操作,例如工具函数或者与类实例无关的全局操作。
所以,静态函数的存在意义在于它们在类的继承层次中有着特定的行为表现,与非静态函数(包括普通成员函数和虚函数)有所区别,能够帮助理解和展示类的静态成员在继承中的不同行为。
帮助理解隐藏的代码:
#include<iostream>
using namespace std;classA{
public:void fun1(int i, int j){cout <<"A::fun1() : " << i <<" " << j << endl;}
};
classB : public A{
public://隐藏void fun1(double i){cout <<"B::fun1() : " << i << endl;}
};
int main(){B b;b.fun1(5);//调用B类中的函数b.fun1(1, 2);//出错,因为基类函数被隐藏system("pause");return 0;
}